Nushell plugin for interacting with D-Bus

implement clippy, formatting suggestions

+795 -515
+146 -86
src/client.rs
··· 1 - use dbus::{channel::{Channel, BusType}, Message, arg::messageitem::MessageItem}; 1 + use dbus::{ 2 + arg::messageitem::MessageItem, 3 + channel::{BusType, Channel}, 4 + Message, 5 + }; 2 6 use nu_plugin::LabeledError; 3 7 use nu_protocol::{Spanned, Value}; 4 8 5 - use crate::{config::{DbusClientConfig, DbusBusChoice}, dbus_type::DbusType, convert::to_message_item, introspection::Node, pattern::Pattern}; 9 + use crate::{ 10 + config::{DbusBusChoice, DbusClientConfig}, 11 + convert::to_message_item, 12 + dbus_type::DbusType, 13 + introspection::Node, 14 + pattern::Pattern, 15 + }; 6 16 7 17 /// Executes D-Bus actions on a connection, handling nushell types 8 18 pub struct DbusClient { ··· 12 22 13 23 // Convenience macros for error handling 14 24 macro_rules! validate_with { 15 - ($type:ty, $spanned:expr) => (<$type>::new(&$spanned.item).map_err(|msg| { 16 - LabeledError { 25 + ($type:ty, $spanned:expr) => { 26 + <$type>::new(&$spanned.item).map_err(|msg| LabeledError { 17 27 label: msg, 18 28 msg: "this argument is incorrect".into(), 19 29 span: Some($spanned.span), 20 - } 21 - })) 30 + }) 31 + }; 22 32 } 23 33 24 34 impl DbusClient { ··· 33 43 ch.register()?; 34 44 Ok(ch) 35 45 }), 36 - }.map_err(|err| { 37 - LabeledError { 38 - label: err.to_string(), 39 - msg: "while connecting to D-Bus as specified here".into(), 40 - span: Some(config.bus_choice.span), 41 - } 46 + } 47 + .map_err(|err| LabeledError { 48 + label: err.to_string(), 49 + msg: "while connecting to D-Bus as specified here".into(), 50 + span: Some(config.bus_choice.span), 42 51 })?; 43 52 Ok(DbusClient { 44 53 config, 45 - conn: channel 54 + conn: channel, 46 55 }) 47 56 } 48 57 ··· 50 59 LabeledError { 51 60 label: err.to_string(), 52 61 msg: msg.to_string(), 53 - span: Some(self.config.span) 62 + span: Some(self.config.span), 54 63 } 55 64 } 56 65 ··· 69 78 valid_dest, 70 79 valid_object, 71 80 "org.freedesktop.DBus.Introspectable", 72 - "Introspect" 73 - ).map_err(|err| self.error(err, context))?; 81 + "Introspect", 82 + ) 83 + .map_err(|err| self.error(err, context))?; 74 84 75 85 // Send and get the response 76 - let resp = self.conn.send_with_reply_and_block(message, self.config.timeout.item) 86 + let resp = self 87 + .conn 88 + .send_with_reply_and_block(message, self.config.timeout.item) 77 89 .map_err(|err| self.error(err, context))?; 78 90 79 91 // Parse it to a Node 80 - let xml: &str = resp.get1() 92 + let xml: &str = resp 93 + .get1() 81 94 .ok_or_else(|| self.error("Introspect method returned the wrong type", context))?; 82 95 83 96 Node::from_xml(xml).map_err(|err| self.error(err, context)) ··· 95 108 96 109 if let Some(sig) = node.get_method_args_signature(&interface.item, &method.item) { 97 110 DbusType::parse_all(&sig).map_err(|err| LabeledError { 98 - label: format!("while getting interface {:?} method {:?} signature: {}", 99 - interface.item, 100 - method.item, 101 - err), 111 + label: format!( 112 + "while getting interface {:?} method {:?} signature: {}", 113 + interface.item, method.item, err 114 + ), 102 115 msg: "try running with --no-introspect or --signature".into(), 103 116 span: Some(self.config.span), 104 117 }) ··· 122 135 let node = self.introspect(dest, object)?; 123 136 124 137 if let Some(sig) = node.get_property_signature(&interface.item, &property.item) { 125 - DbusType::parse_all(&sig).map_err(|err| LabeledError { 126 - label: format!("while getting interface {:?} property {:?} signature: {}", 127 - interface.item, 128 - property.item, 129 - err), 138 + DbusType::parse_all(sig).map_err(|err| LabeledError { 139 + label: format!( 140 + "while getting interface {:?} property {:?} signature: {}", 141 + interface.item, property.item, err 142 + ), 130 143 msg: "try running with --no-introspect or --signature".into(), 131 144 span: Some(self.config.span), 132 145 }) 133 146 } else { 134 147 Err(LabeledError { 135 - label: format!("Property {:?} not found on {:?}", property.item, interface.item), 148 + label: format!( 149 + "Property {:?} not found on {:?}", 150 + property.item, interface.item 151 + ), 136 152 msg: "check that this property/interface is correct".into(), 137 153 span: Some(property.span), 138 154 }) ··· 158 174 let valid_method = validate_with!(dbus::strings::Member, method)?; 159 175 160 176 // Parse the signature 161 - let mut valid_signature = signature.map(|s| DbusType::parse_all(&s.item).map_err(|err| { 162 - LabeledError { 163 - label: err, 164 - msg: "in signature specified here".into(), 165 - span: Some(s.span), 166 - } 167 - })).transpose()?; 177 + let mut valid_signature = signature 178 + .map(|s| { 179 + DbusType::parse_all(&s.item).map_err(|err| LabeledError { 180 + label: err, 181 + msg: "in signature specified here".into(), 182 + span: Some(s.span), 183 + }) 184 + }) 185 + .transpose()?; 168 186 169 187 // If not provided, try introspection (unless disabled) 170 188 if valid_signature.is_none() && self.config.introspect { 171 189 match self.get_method_signature_by_introspection(dest, object, interface, method) { 172 190 Ok(sig) => { 173 191 valid_signature = Some(sig); 174 - }, 192 + } 175 193 Err(err) => { 176 - eprintln!("Warning: D-Bus introspection failed on {:?}. \ 194 + eprintln!( 195 + "Warning: D-Bus introspection failed on {:?}. \ 177 196 Use `--no-introspect` or pass `--signature` to silence this warning. \ 178 197 Cause: {}", 179 - object.item, 180 - err.label); 198 + object.item, err.label 199 + ); 181 200 } 182 201 } 183 202 } 184 203 185 204 if let Some(sig) = &valid_signature { 186 205 if sig.len() != args.len() { 187 - self.error(format!("expected {} arguments, got {}", sig.len(), args.len()), context); 206 + self.error( 207 + format!("expected {} arguments, got {}", sig.len(), args.len()), 208 + context, 209 + ); 188 210 } 189 211 } 190 212 191 213 // Construct the method call message 192 - let mut message = Message::new_method_call( 193 - valid_dest, 194 - valid_object, 195 - valid_interface, 196 - valid_method, 197 - ).map_err(|err| self.error(err, context))?; 214 + let mut message = 215 + Message::new_method_call(valid_dest, valid_object, valid_interface, valid_method) 216 + .map_err(|err| self.error(err, context))?; 198 217 199 218 // Convert the args to message items 200 - let sigs_iter = valid_signature.iter().flatten().map(Some).chain(std::iter::repeat(None)); 219 + let sigs_iter = valid_signature 220 + .iter() 221 + .flatten() 222 + .map(Some) 223 + .chain(std::iter::repeat(None)); 201 224 for (val, sig) in args.iter().zip(sigs_iter) { 202 225 message = message.append1(to_message_item(val, sig)?); 203 226 } 204 227 205 228 // Send it on the channel and get the response 206 - let resp = self.conn.send_with_reply_and_block(message, self.config.timeout.item) 229 + let resp = self 230 + .conn 231 + .send_with_reply_and_block(message, self.config.timeout.item) 207 232 .map_err(|err| self.error(err, context))?; 208 233 209 234 crate::convert::from_message(&resp, self.config.span) ··· 224 249 self.call( 225 250 dest, 226 251 object, 227 - &Spanned { item: "org.freedesktop.DBus.Properties".into(), span: self.config.span }, 228 - &Spanned { item: "Get".into(), span: self.config.span }, 229 - Some(&Spanned { item: "ss".into(), span: self.config.span }), 230 - &[interface_val, property_val] 231 - ).map(|val| val.into_iter().nth(0).unwrap_or_default()) 252 + &Spanned { 253 + item: "org.freedesktop.DBus.Properties".into(), 254 + span: self.config.span, 255 + }, 256 + &Spanned { 257 + item: "Get".into(), 258 + span: self.config.span, 259 + }, 260 + Some(&Spanned { 261 + item: "ss".into(), 262 + span: self.config.span, 263 + }), 264 + &[interface_val, property_val], 265 + ) 266 + .map(|val| val.into_iter().nth(0).unwrap_or_default()) 232 267 } 233 268 234 269 /// Get all D-Bus properties from the given object ··· 243 278 self.call( 244 279 dest, 245 280 object, 246 - &Spanned { item: "org.freedesktop.DBus.Properties".into(), span: self.config.span }, 247 - &Spanned { item: "GetAll".into(), span: self.config.span }, 248 - Some(&Spanned { item: "s".into(), span: self.config.span }), 249 - &[interface_val] 250 - ).map(|val| val.into_iter().nth(0).unwrap_or_default()) 281 + &Spanned { 282 + item: "org.freedesktop.DBus.Properties".into(), 283 + span: self.config.span, 284 + }, 285 + &Spanned { 286 + item: "GetAll".into(), 287 + span: self.config.span, 288 + }, 289 + Some(&Spanned { 290 + item: "s".into(), 291 + span: self.config.span, 292 + }), 293 + &[interface_val], 294 + ) 295 + .map(|val| val.into_iter().nth(0).unwrap_or_default()) 251 296 } 252 297 253 298 /// Set a D-Bus property on the given object ··· 267 312 let valid_object = validate_with!(dbus::strings::Path, object)?; 268 313 269 314 // Parse the signature 270 - let mut valid_signature = signature.map(|s| DbusType::parse_all(&s.item).map_err(|err| { 271 - LabeledError { 272 - label: err, 273 - msg: "in signature specified here".into(), 274 - span: Some(s.span), 275 - } 276 - })).transpose()?; 315 + let mut valid_signature = signature 316 + .map(|s| { 317 + DbusType::parse_all(&s.item).map_err(|err| LabeledError { 318 + label: err, 319 + msg: "in signature specified here".into(), 320 + span: Some(s.span), 321 + }) 322 + }) 323 + .transpose()?; 277 324 278 325 // If not provided, try introspection (unless disabled) 279 326 if valid_signature.is_none() && self.config.introspect { 280 327 match self.get_property_signature_by_introspection(dest, object, interface, property) { 281 328 Ok(sig) => { 282 329 valid_signature = Some(sig); 283 - }, 330 + } 284 331 Err(err) => { 285 - eprintln!("Warning: D-Bus introspection failed on {:?}. \ 332 + eprintln!( 333 + "Warning: D-Bus introspection failed on {:?}. \ 286 334 Use `--no-introspect` or pass `--signature` to silence this warning. \ 287 335 Cause: {}", 288 - object.item, 289 - err.label); 336 + object.item, err.label 337 + ); 290 338 } 291 339 } 292 340 } 293 341 294 342 if let Some(sig) = &valid_signature { 295 343 if sig.len() != 1 { 296 - self.error(format!( 297 - "expected single object signature, but there are {}", sig.len()), context); 344 + self.error( 345 + format!( 346 + "expected single object signature, but there are {}", 347 + sig.len() 348 + ), 349 + context, 350 + ); 298 351 } 299 352 } 300 353 ··· 304 357 valid_object, 305 358 "org.freedesktop.DBus.Properties", 306 359 "Set", 307 - ).map_err(|err| self.error(err, context))? 308 - .append2(&interface.item, &property.item) 309 - .append1( 310 - // Box it in a variant as required for property setting 311 - MessageItem::Variant(Box::new( 312 - to_message_item(value, valid_signature.as_ref().map(|s| &s[0]))?)) 313 - ); 360 + ) 361 + .map_err(|err| self.error(err, context))? 362 + .append2(&interface.item, &property.item) 363 + .append1( 364 + // Box it in a variant as required for property setting 365 + MessageItem::Variant(Box::new(to_message_item( 366 + value, 367 + valid_signature.as_ref().map(|s| &s[0]), 368 + )?)), 369 + ); 314 370 315 371 // Send it on the channel and get the response 316 - self.conn.send_with_reply_and_block(message, self.config.timeout.item) 372 + self.conn 373 + .send_with_reply_and_block(message, self.config.timeout.item) 317 374 .map_err(|err| self.error(err, context))?; 318 375 319 376 Ok(()) 320 377 } 321 378 322 - pub fn list(&self, pattern: Option<&Pattern>) 323 - -> Result<Vec<String>, LabeledError> 324 - { 379 + pub fn list(&self, pattern: Option<&Pattern>) -> Result<Vec<String>, LabeledError> { 325 380 let context = "while listing D-Bus connection names"; 326 381 327 382 let message = Message::new_method_call( 328 383 "org.freedesktop.DBus", 329 384 "/org/freedesktop/DBus", 330 385 "org.freedesktop.DBus", 331 - "ListNames" 332 - ).map_err(|err| self.error(err, context))?; 386 + "ListNames", 387 + ) 388 + .map_err(|err| self.error(err, context))?; 333 389 334 - self.conn.send_with_reply_and_block(message, self.config.timeout.item) 390 + self.conn 391 + .send_with_reply_and_block(message, self.config.timeout.item) 335 392 .map_err(|err| self.error(err, context)) 336 393 .and_then(|reply| reply.read1().map_err(|err| self.error(err, context))) 337 394 .map(|names: Vec<String>| { 338 395 // Filter the names by the pattern 339 396 if let Some(pattern) = pattern { 340 - names.into_iter().filter(|name| pattern.is_match(name)).collect() 397 + names 398 + .into_iter() 399 + .filter(|name| pattern.is_match(name)) 400 + .collect() 341 401 } else { 342 402 names 343 403 }
+33 -18
src/config.rs
··· 1 1 use std::time::Duration; 2 2 3 3 use nu_plugin::{EvaluatedCall, LabeledError}; 4 - use nu_protocol::{Spanned, Span}; 4 + use nu_protocol::{Span, Spanned}; 5 5 6 6 /// General configuration related to the D-Bus client connection 7 7 #[derive(Debug, Clone)] ··· 37 37 fn try_from(call: &EvaluatedCall) -> Result<Self, Self::Error> { 38 38 let mut config = DbusClientConfig { 39 39 span: call.head, 40 - bus_choice: Spanned { item: DbusBusChoice::default(), span: call.head }, 41 - timeout: Spanned { item: Duration::from_secs(2), span: call.head }, 40 + bus_choice: Spanned { 41 + item: DbusBusChoice::default(), 42 + span: call.head, 43 + }, 44 + timeout: Spanned { 45 + item: Duration::from_secs(2), 46 + span: call.head, 47 + }, 42 48 introspect: true, 43 49 }; 44 50 ··· 51 57 "session" => DbusBusChoice::Session, 52 58 "system" => DbusBusChoice::System, 53 59 "started" => DbusBusChoice::Started, 54 - _ => unreachable!() 60 + _ => unreachable!(), 55 61 }; 56 - config.bus_choice = Spanned { item: dest, span: name.span }; 62 + config.bus_choice = Spanned { 63 + item: dest, 64 + span: name.span, 65 + }; 57 66 } 58 - }, 67 + } 59 68 r#type @ ("bus" | "peer") => { 60 69 if let Some(value) = value { 61 70 let address = value.as_str()?; 62 71 let dest = match r#type { 63 72 "bus" => DbusBusChoice::Bus(address.to_owned()), 64 73 "peer" => DbusBusChoice::Peer(address.to_owned()), 65 - _ => unreachable!() 74 + _ => unreachable!(), 75 + }; 76 + config.bus_choice = Spanned { 77 + item: dest, 78 + span: value.span(), 66 79 }; 67 - config.bus_choice = Spanned { item: dest, span: value.span() }; 68 80 } 69 - }, 81 + } 70 82 "timeout" => { 71 83 if let Some(value) = value { 72 - let nanos: u64 = value.as_duration()?.try_into().map_err(|_| { 73 - LabeledError { 84 + let nanos: u64 = 85 + value.as_duration()?.try_into().map_err(|_| LabeledError { 74 86 label: "Timeout must be a positive duration".into(), 75 87 msg: "invalid timeout specified here".into(), 76 88 span: Some(value.span()), 77 - } 78 - })?; 89 + })?; 79 90 let item = Duration::from_nanos(nanos); 80 - config.timeout = Spanned { item, span: value.span() }; 91 + config.timeout = Spanned { 92 + item, 93 + span: value.span(), 94 + }; 81 95 } 82 - }, 96 + } 83 97 "no-introspect" => { 84 - config.introspect = !value.as_ref() 98 + config.introspect = !value 99 + .as_ref() 85 100 .and_then(|v| v.as_bool().ok()) 86 101 .unwrap_or(false); 87 - }, 88 - _ => () 102 + } 103 + _ => (), 89 104 } 90 105 } 91 106
+175 -118
src/convert.rs
··· 1 - use dbus::{Message, arg::{ArgType, RefArg, messageitem::{MessageItemArray, MessageItem, MessageItemDict}}, Signature}; 1 + use dbus::{ 2 + arg::{ 3 + messageitem::{MessageItem, MessageItemArray, MessageItemDict}, 4 + ArgType, RefArg, 5 + }, 6 + Message, Signature, 7 + }; 2 8 use nu_plugin::LabeledError; 3 - use nu_protocol::{Value, Span, Record}; 9 + use nu_protocol::{Record, Span, Value}; 4 10 use std::str::FromStr; 5 11 6 12 use crate::dbus_type::DbusType; ··· 31 37 Value::record(record, span) 32 38 } else if &*refarg.signature() == "ay" { 33 39 // Byte array - better to return as binary 34 - let bytes = dbus::arg::cast::<Vec<u8>>(&refarg.box_clone()).unwrap().to_owned(); 40 + let bytes = dbus::arg::cast::<Vec<u8>>(&refarg.box_clone()) 41 + .unwrap() 42 + .to_owned(); 35 43 Value::binary(bytes, span) 36 44 } else { 37 45 // It's an array 38 46 Value::list( 39 - refarg.as_iter().unwrap().map(|v| from_refarg(v, span)).flatten().collect(), 40 - span) 47 + refarg 48 + .as_iter() 49 + .unwrap() 50 + .flat_map(|v| from_refarg(v, span)) 51 + .collect(), 52 + span, 53 + ) 41 54 } 42 - }, 55 + } 43 56 ArgType::Variant => { 44 - let inner = refarg.as_iter().unwrap().nth(0).unwrap(); 57 + let inner = refarg.as_iter().unwrap().next().unwrap(); 45 58 return from_refarg(inner, span); 46 - }, 47 - ArgType::Boolean => 48 - Value::bool(refarg.as_i64().unwrap() != 0, span), 59 + } 60 + ArgType::Boolean => Value::bool(refarg.as_i64().unwrap() != 0, span), 49 61 50 62 // Strings 51 - ArgType::String | ArgType::ObjectPath | ArgType::Signature => 52 - Value::string(refarg.as_str().unwrap(), span), 63 + ArgType::String | ArgType::ObjectPath | ArgType::Signature => { 64 + Value::string(refarg.as_str().unwrap(), span) 65 + } 53 66 // Ints 54 - ArgType::Byte | ArgType::Int16 | ArgType::UInt16 | ArgType::Int32 | 55 - ArgType::UInt32 | ArgType::Int64 | ArgType::UnixFd => 56 - Value::int(refarg.as_i64().unwrap(), span), 67 + ArgType::Byte 68 + | ArgType::Int16 69 + | ArgType::UInt16 70 + | ArgType::Int32 71 + | ArgType::UInt32 72 + | ArgType::Int64 73 + | ArgType::UnixFd => Value::int(refarg.as_i64().unwrap(), span), 57 74 58 75 // Nushell doesn't support u64, so present it as a string 59 76 ArgType::UInt64 => Value::string(refarg.as_u64().unwrap().to_string(), span), 60 77 61 78 // Floats 62 - ArgType::Double => 63 - Value::float(refarg.as_f64().unwrap(), span), 79 + ArgType::Double => Value::float(refarg.as_f64().unwrap(), span), 64 80 65 - ArgType::Struct => 66 - Value::list( 67 - refarg.as_iter().unwrap().map(|v| from_refarg(v, span)).flatten().collect(), 68 - span), 81 + ArgType::Struct => Value::list( 82 + refarg 83 + .as_iter() 84 + .unwrap() 85 + .flat_map(|v| from_refarg(v, span)) 86 + .collect(), 87 + span, 88 + ), 69 89 70 - ArgType::DictEntry => 71 - return Err("Encountered dictionary entry outside of dictionary".into()), 72 - ArgType::Invalid => 73 - return Err("Encountered invalid D-Bus value".into()), 90 + ArgType::DictEntry => { 91 + return Err("Encountered dictionary entry outside of dictionary".into()) 92 + } 93 + ArgType::Invalid => return Err("Encountered invalid D-Bus value".into()), 74 94 }) 75 95 } 76 96 77 - pub fn to_message_item(value: &Value, expected_type: Option<&DbusType>) 78 - -> Result<MessageItem, LabeledError> 79 - { 97 + pub fn to_message_item( 98 + value: &Value, 99 + expected_type: Option<&DbusType>, 100 + ) -> Result<MessageItem, LabeledError> { 80 101 // Report errors from conversion. Error must support Display 81 102 macro_rules! try_convert { 82 - ($result_expr:expr) => ($result_expr.map_err(|err| LabeledError { 83 - label: format!("Failed to convert value to the D-Bus `{:?}` type", 84 - expected_type.unwrap()), 85 - msg: err.to_string(), 86 - span: Some(value.span()), 87 - })?) 103 + ($result_expr:expr) => { 104 + $result_expr.map_err(|err| LabeledError { 105 + label: format!( 106 + "Failed to convert value to the D-Bus `{:?}` type", 107 + expected_type.unwrap() 108 + ), 109 + msg: err.to_string(), 110 + span: Some(value.span()), 111 + })? 112 + }; 88 113 } 89 114 90 115 // Try to match values to expected types 91 116 match (value, expected_type) { 92 117 // Boolean 93 - (Value::Bool { val, .. }, Some(DbusType::Boolean)) => 94 - Ok(MessageItem::Bool(*val)), 118 + (Value::Bool { val, .. }, Some(DbusType::Boolean)) => Ok(MessageItem::Bool(*val)), 95 119 96 120 // Strings and specialized strings 97 - (Value::String { val, .. }, Some(DbusType::String)) => 98 - Ok(MessageItem::Str(val.to_owned())), 99 - (Value::String { val, .. }, Some(DbusType::ObjectPath)) => 100 - Ok(MessageItem::ObjectPath(try_convert!(dbus::strings::Path::new(val)))), 101 - (Value::String { val, .. }, Some(DbusType::Signature)) => 102 - Ok(MessageItem::Signature(try_convert!(dbus::strings::Signature::new(val)))), 121 + (Value::String { val, .. }, Some(DbusType::String)) => Ok(MessageItem::Str(val.to_owned())), 122 + (Value::String { val, .. }, Some(DbusType::ObjectPath)) => Ok(MessageItem::ObjectPath( 123 + try_convert!(dbus::strings::Path::new(val)), 124 + )), 125 + (Value::String { val, .. }, Some(DbusType::Signature)) => Ok(MessageItem::Signature( 126 + try_convert!(dbus::strings::Signature::new(val)), 127 + )), 103 128 104 129 // Signed ints 105 - (Value::Int { val, .. }, Some(DbusType::Int64)) => 106 - Ok(MessageItem::Int64(*val)), 107 - (Value::Int { val, .. }, Some(DbusType::Int32)) => 108 - Ok(MessageItem::Int32(try_convert!(i32::try_from(*val)))), 109 - (Value::Int { val, .. }, Some(DbusType::Int16)) => 110 - Ok(MessageItem::Int16(try_convert!(i16::try_from(*val)))), 130 + (Value::Int { val, .. }, Some(DbusType::Int64)) => Ok(MessageItem::Int64(*val)), 131 + (Value::Int { val, .. }, Some(DbusType::Int32)) => { 132 + Ok(MessageItem::Int32(try_convert!(i32::try_from(*val)))) 133 + } 134 + (Value::Int { val, .. }, Some(DbusType::Int16)) => { 135 + Ok(MessageItem::Int16(try_convert!(i16::try_from(*val)))) 136 + } 111 137 112 138 // Unsigned ints 113 - (Value::Int { val, .. }, Some(DbusType::UInt64)) => 114 - Ok(MessageItem::UInt64(try_convert!(u64::try_from(*val)))), 115 - (Value::Int { val, .. }, Some(DbusType::UInt32)) => 116 - Ok(MessageItem::UInt32(try_convert!(u32::try_from(*val)))), 117 - (Value::Int { val, .. }, Some(DbusType::UInt16)) => 118 - Ok(MessageItem::UInt16(try_convert!(u16::try_from(*val)))), 119 - (Value::Int { val, .. }, Some(DbusType::Byte)) => 120 - Ok(MessageItem::Byte(try_convert!(u8::try_from(*val)))), 139 + (Value::Int { val, .. }, Some(DbusType::UInt64)) => { 140 + Ok(MessageItem::UInt64(try_convert!(u64::try_from(*val)))) 141 + } 142 + (Value::Int { val, .. }, Some(DbusType::UInt32)) => { 143 + Ok(MessageItem::UInt32(try_convert!(u32::try_from(*val)))) 144 + } 145 + (Value::Int { val, .. }, Some(DbusType::UInt16)) => { 146 + Ok(MessageItem::UInt16(try_convert!(u16::try_from(*val)))) 147 + } 148 + (Value::Int { val, .. }, Some(DbusType::Byte)) => { 149 + Ok(MessageItem::Byte(try_convert!(u8::try_from(*val)))) 150 + } 121 151 122 152 // Ints from string 123 - (Value::String { val, .. }, Some(DbusType::Int64)) => 124 - Ok(MessageItem::Int64(try_convert!(i64::from_str(&val[..])))), 125 - (Value::String { val, .. }, Some(DbusType::Int32)) => 126 - Ok(MessageItem::Int32(try_convert!(i32::from_str(&val[..])))), 127 - (Value::String { val, .. }, Some(DbusType::Int16)) => 128 - Ok(MessageItem::Int16(try_convert!(i16::from_str(&val[..])))), 129 - (Value::String { val, .. }, Some(DbusType::UInt64)) => 130 - Ok(MessageItem::UInt64(try_convert!(u64::from_str(&val[..])))), 131 - (Value::String { val, .. }, Some(DbusType::UInt32)) => 132 - Ok(MessageItem::UInt32(try_convert!(u32::from_str(&val[..])))), 133 - (Value::String { val, .. }, Some(DbusType::UInt16)) => 134 - Ok(MessageItem::UInt16(try_convert!(u16::from_str(&val[..])))), 135 - (Value::String { val, .. }, Some(DbusType::Byte)) => 136 - Ok(MessageItem::Byte(try_convert!(u8::from_str(&val[..])))), 153 + (Value::String { val, .. }, Some(DbusType::Int64)) => { 154 + Ok(MessageItem::Int64(try_convert!(i64::from_str(&val[..])))) 155 + } 156 + (Value::String { val, .. }, Some(DbusType::Int32)) => { 157 + Ok(MessageItem::Int32(try_convert!(i32::from_str(&val[..])))) 158 + } 159 + (Value::String { val, .. }, Some(DbusType::Int16)) => { 160 + Ok(MessageItem::Int16(try_convert!(i16::from_str(&val[..])))) 161 + } 162 + (Value::String { val, .. }, Some(DbusType::UInt64)) => { 163 + Ok(MessageItem::UInt64(try_convert!(u64::from_str(&val[..])))) 164 + } 165 + (Value::String { val, .. }, Some(DbusType::UInt32)) => { 166 + Ok(MessageItem::UInt32(try_convert!(u32::from_str(&val[..])))) 167 + } 168 + (Value::String { val, .. }, Some(DbusType::UInt16)) => { 169 + Ok(MessageItem::UInt16(try_convert!(u16::from_str(&val[..])))) 170 + } 171 + (Value::String { val, .. }, Some(DbusType::Byte)) => { 172 + Ok(MessageItem::Byte(try_convert!(u8::from_str(&val[..])))) 173 + } 137 174 138 175 // Float 139 - (Value::Float { val, .. }, Some(DbusType::Double)) => 140 - Ok(MessageItem::Double(*val)), 141 - (Value::String { val, .. }, Some(DbusType::Double)) => 142 - Ok(MessageItem::Double(try_convert!(f64::from_str(&val[..])))), 176 + (Value::Float { val, .. }, Some(DbusType::Double)) => Ok(MessageItem::Double(*val)), 177 + (Value::String { val, .. }, Some(DbusType::Double)) => { 178 + Ok(MessageItem::Double(try_convert!(f64::from_str(&val[..])))) 179 + } 143 180 144 181 // Binary 145 182 (Value::Binary { val, .. }, Some(r#type @ DbusType::Array(content_type))) ··· 147 184 { 148 185 // FIXME: this is likely pretty inefficient for a bunch of bytes 149 186 let sig = Signature::from(r#type.stringify()); 150 - let items = val.iter().cloned().map(MessageItem::Byte).collect::<Vec<_>>(); 151 - Ok(MessageItem::Array(MessageItemArray::new(items, sig).unwrap())) 152 - }, 187 + let items = val 188 + .iter() 189 + .cloned() 190 + .map(MessageItem::Byte) 191 + .collect::<Vec<_>>(); 192 + Ok(MessageItem::Array( 193 + MessageItemArray::new(items, sig).unwrap(), 194 + )) 195 + } 153 196 154 197 // List/array 155 198 (Value::List { vals, .. }, Some(r#type @ DbusType::Array(content_type))) => { 156 199 let sig = Signature::from(r#type.stringify()); 157 - let items = vals.iter() 200 + let items = vals 201 + .iter() 158 202 .map(|content| to_message_item(content, Some(content_type))) 159 203 .collect::<Result<Vec<MessageItem>, _>>()?; 160 - Ok(MessageItem::Array(MessageItemArray::new(items, sig).unwrap())) 161 - }, 204 + Ok(MessageItem::Array( 205 + MessageItemArray::new(items, sig).unwrap(), 206 + )) 207 + } 162 208 163 209 // Struct 164 210 (Value::List { vals, .. }, Some(DbusType::Struct(types))) => { 165 211 if vals.len() != types.len() { 166 212 return Err(LabeledError { 167 - label: format!("expected struct with {} element(s) ({:?})", types.len(), types), 213 + label: format!( 214 + "expected struct with {} element(s) ({:?})", 215 + types.len(), 216 + types 217 + ), 168 218 msg: format!("this list has {} element(s) instead", vals.len()), 169 - span: Some(value.span()) 219 + span: Some(value.span()), 170 220 }); 171 221 } 172 - let items = vals.iter().zip(types) 222 + let items = vals 223 + .iter() 224 + .zip(types) 173 225 .map(|(content, r#type)| to_message_item(content, Some(r#type))) 174 226 .collect::<Result<Vec<MessageItem>, _>>()?; 175 227 Ok(MessageItem::Struct(items)) 176 - }, 228 + } 177 229 178 230 // Record/dict 179 231 (Value::Record { val, .. }, Some(DbusType::Array(content_type))) ··· 182 234 if let DbusType::DictEntry(ref key_type, ref val_type) = **content_type { 183 235 let key_sig = Signature::from(key_type.stringify()); 184 236 let val_sig = Signature::from(val_type.stringify()); 185 - let pairs = val.iter() 237 + let pairs = val 238 + .iter() 186 239 .map(|(key, val)| { 187 240 let key_as_value = Value::string(key, value.span()); 188 241 let key_message_item = to_message_item(&key_as_value, Some(key_type))?; ··· 190 243 Ok((key_message_item, val_message_item)) 191 244 }) 192 245 .collect::<Result<Vec<_>, LabeledError>>()?; 193 - Ok(MessageItem::Dict(MessageItemDict::new(pairs, key_sig, val_sig).unwrap())) 246 + Ok(MessageItem::Dict( 247 + MessageItemDict::new(pairs, key_sig, val_sig).unwrap(), 248 + )) 194 249 } else { 195 250 unreachable!() 196 251 } 197 - }, 252 + } 198 253 199 254 // Variant - use automatic type 200 - (other_value, Some(DbusType::Variant)) => 201 - Ok(MessageItem::Variant(Box::new(to_message_item(other_value, None)?))), 255 + (other_value, Some(DbusType::Variant)) => Ok(MessageItem::Variant(Box::new( 256 + to_message_item(other_value, None)?, 257 + ))), 202 258 203 259 // Value not compatible with expected type 204 - (other_value, Some(expectation)) => 205 - Err(LabeledError { 206 - label: format!("`{}` can not be converted to the D-Bus `{:?}` type", 207 - other_value.get_type(), expectation), 208 - msg: format!("expected a `{:?}` here", expectation), 209 - span: Some(other_value.span()), 210 - }), 260 + (other_value, Some(expectation)) => Err(LabeledError { 261 + label: format!( 262 + "`{}` can not be converted to the D-Bus `{:?}` type", 263 + other_value.get_type(), 264 + expectation 265 + ), 266 + msg: format!("expected a `{:?}` here", expectation), 267 + span: Some(other_value.span()), 268 + }), 211 269 212 270 // Automatic types (with no type expectation) 213 - (Value::String { .. }, None) => 214 - to_message_item(value, Some(&DbusType::String)), 215 - (Value::Int { .. }, None) => 216 - to_message_item(value, Some(&DbusType::Int64)), 217 - (Value::Float { .. }, None) => 218 - to_message_item(value, Some(&DbusType::Double)), 219 - (Value::Bool { .. }, None) => 220 - to_message_item(value, Some(&DbusType::Boolean)), 221 - (Value::List { .. }, None) => 222 - to_message_item(value, Some(&DbusType::Array(DbusType::Variant.into()))), 223 - (Value::Record { .. }, None) => 224 - to_message_item(value, Some(&DbusType::Array( 225 - DbusType::DictEntry( 226 - DbusType::String.into(), 227 - DbusType::Variant.into() 228 - ).into()))), 271 + (Value::String { .. }, None) => to_message_item(value, Some(&DbusType::String)), 272 + (Value::Int { .. }, None) => to_message_item(value, Some(&DbusType::Int64)), 273 + (Value::Float { .. }, None) => to_message_item(value, Some(&DbusType::Double)), 274 + (Value::Bool { .. }, None) => to_message_item(value, Some(&DbusType::Boolean)), 275 + (Value::List { .. }, None) => { 276 + to_message_item(value, Some(&DbusType::Array(DbusType::Variant.into()))) 277 + } 278 + (Value::Record { .. }, None) => to_message_item( 279 + value, 280 + Some(&DbusType::Array( 281 + DbusType::DictEntry(DbusType::String.into(), DbusType::Variant.into()).into(), 282 + )), 283 + ), 229 284 230 285 // No expected type, but can't handle this type 231 - _ => 232 - Err(LabeledError { 233 - label: format!("can not use values of type `{}` in D-Bus calls", value.get_type()), 234 - msg: "use a supported type here instead".into(), 235 - span: Some(value.span()), 236 - }) 286 + _ => Err(LabeledError { 287 + label: format!( 288 + "can not use values of type `{}` in D-Bus calls", 289 + value.get_type() 290 + ), 291 + msg: "use a supported type here instead".into(), 292 + span: Some(value.span()), 293 + }), 237 294 } 238 295 }
+72 -60
src/dbus_type.rs
··· 48 48 // The next type is the content type of the array 49 49 let (content_type, remainder) = Self::parse(&input[1..])?; 50 50 Ok((Array(content_type.into()), remainder)) 51 - }, 51 + } 52 52 '(' => { 53 53 // Parse the struct content until we get to the end ) char 54 54 let mut remainder = &input[1..]; ··· 56 56 loop { 57 57 if remainder.is_empty() { 58 58 break Err("unexpected end of D-Bus type string \ 59 - before end of array".into()); 60 - } else if remainder.starts_with(')') { 61 - break Ok((DbusType::Struct(types), &remainder[1..])); 59 + before end of array" 60 + .into()); 61 + } else if let Some(new_remainder) = remainder.strip_prefix(')') { 62 + break Ok((DbusType::Struct(types), new_remainder)); 62 63 } else { 63 64 let (r#type, new_remainder) = Self::parse(remainder)?; 64 65 types.push(r#type); 65 66 remainder = new_remainder; 66 67 } 67 68 } 68 - }, 69 + } 69 70 'v' => Ok((Variant, &input[1..])), 70 71 '{' => { 71 72 // Expect two types 72 73 let (key_type, key_remainder) = Self::parse(&input[1..])?; 73 74 let (val_type, val_remainder) = Self::parse(key_remainder)?; 74 75 // Must end with } 75 - if val_remainder.starts_with('}') { 76 - Ok((DbusType::DictEntry(key_type.into(), val_type.into()), &val_remainder[1..])) 76 + if let Some(new_remainder) = val_remainder.strip_prefix('}') { 77 + Ok(( 78 + DbusType::DictEntry(key_type.into(), val_type.into()), 79 + new_remainder, 80 + )) 77 81 } else { 78 - Err(format!("expected `}}` char to end dictionary in D-Bus type \ 79 - but remainder is {:?}", val_remainder)) 82 + Err(format!( 83 + "expected `}}` char to end dictionary in D-Bus type \ 84 + but remainder is {:?}", 85 + val_remainder 86 + )) 80 87 } 81 - }, 82 - other => Err(format!("unexpected char {other:?} in D-Bus type representation")) 88 + } 89 + other => Err(format!( 90 + "unexpected char {other:?} in D-Bus type representation" 91 + )), 83 92 } 84 93 } 85 94 ··· 99 108 use self::DbusType::*; 100 109 101 110 match self { 102 - Byte => 'y'.into(), 103 - Boolean => 'b'.into(), 104 - Int16 => 'n'.into(), 105 - UInt16 => 'q'.into(), 106 - Int32 => 'i'.into(), 107 - UInt32 => 'u'.into(), 108 - Int64 => 'x'.into(), 109 - UInt64 => 't'.into(), 110 - Double => 'd'.into(), 111 - String => 's'.into(), 111 + Byte => 'y'.into(), 112 + Boolean => 'b'.into(), 113 + Int16 => 'n'.into(), 114 + UInt16 => 'q'.into(), 115 + Int32 => 'i'.into(), 116 + UInt32 => 'u'.into(), 117 + Int64 => 'x'.into(), 118 + UInt64 => 't'.into(), 119 + Double => 'd'.into(), 120 + String => 's'.into(), 112 121 ObjectPath => 'o'.into(), 113 - Signature => 'g'.into(), 122 + Signature => 'g'.into(), 114 123 115 124 // a<type> 116 125 Array(content) => format!("a{}", content.stringify()), ··· 131 140 132 141 #[cfg(test)] 133 142 macro_rules! should_parse_to { 134 - ($str:expr, $result:expr) => ( 143 + ($str:expr, $result:expr) => { 135 144 assert_eq!(DbusType::parse($str), Ok(($result, ""))) 136 - ) 145 + }; 137 146 } 138 147 139 148 #[test] ··· 204 213 use self::DbusType::*; 205 214 should_parse_to!("((xx))", Struct(vec![Struct(vec![Int64, Int64])])); 206 215 should_parse_to!("(y(xx))", Struct(vec![Byte, Struct(vec![Int64, Int64])])); 207 - should_parse_to!("(y(ss)o)", Struct(vec![Byte, Struct(vec![String, String]), ObjectPath])); 216 + should_parse_to!( 217 + "(y(ss)o)", 218 + Struct(vec![Byte, Struct(vec![String, String]), ObjectPath]) 219 + ); 208 220 should_parse_to!("((yy)s)", Struct(vec![Struct(vec![Byte, Byte]), String])); 209 221 } 210 222 ··· 224 236 fn test_parse_dict_entry() { 225 237 use self::DbusType::*; 226 238 should_parse_to!("{ss}", DictEntry(String.into(), String.into())); 227 - should_parse_to!("{s(bd)}", DictEntry(String.into(), Struct(vec![Boolean, Double]).into())); 239 + should_parse_to!( 240 + "{s(bd)}", 241 + DictEntry(String.into(), Struct(vec![Boolean, Double]).into()) 242 + ); 228 243 } 229 244 230 245 #[test] 231 246 fn test_parse_array_dict() { 232 247 use self::DbusType::*; 233 - should_parse_to!("a{sd}", Array(DictEntry(String.into(), Double.into()).into())); 248 + should_parse_to!( 249 + "a{sd}", 250 + Array(DictEntry(String.into(), Double.into()).into()) 251 + ); 234 252 } 235 253 236 254 #[test] ··· 249 267 fn test_parse_all() { 250 268 use self::DbusType::*; 251 269 assert_eq!(DbusType::parse_all(""), Ok(vec![])); 252 - assert_eq!( 253 - DbusType::parse_all("s"), 254 - Ok(vec![ 255 - String, 256 - ]) 257 - ); 270 + assert_eq!(DbusType::parse_all("s"), Ok(vec![String,])); 258 271 assert_eq!( 259 272 DbusType::parse_all("isbb"), 260 - Ok(vec![ 261 - Int32, 262 - String, 263 - Boolean, 264 - Boolean, 265 - ]) 273 + Ok(vec![Int32, String, Boolean, Boolean,]) 266 274 ); 267 275 assert_eq!( 268 276 DbusType::parse_all("ia{s(bi)}s"), ··· 276 284 277 285 #[cfg(test)] 278 286 macro_rules! should_stringify_to { 279 - ($type:expr, $result:expr) => ( 287 + ($type:expr, $result:expr) => { 280 288 assert_eq!(DbusType::stringify(&$type), $result) 281 - ) 289 + }; 282 290 } 283 291 284 292 #[test] 285 293 fn test_stringify_simple_types() { 286 294 use self::DbusType::*; 287 - should_stringify_to!(Byte, "y"); 288 - should_stringify_to!(Boolean, "b"); 289 - should_stringify_to!(Int16, "n"); 290 - should_stringify_to!(UInt16, "q"); 291 - should_stringify_to!(Int32, "i"); 292 - should_stringify_to!(UInt32, "u"); 293 - should_stringify_to!(Int64, "x"); 294 - should_stringify_to!(UInt64, "t"); 295 - should_stringify_to!(Double, "d"); 296 - should_stringify_to!(String, "s"); 295 + should_stringify_to!(Byte, "y"); 296 + should_stringify_to!(Boolean, "b"); 297 + should_stringify_to!(Int16, "n"); 298 + should_stringify_to!(UInt16, "q"); 299 + should_stringify_to!(Int32, "i"); 300 + should_stringify_to!(UInt32, "u"); 301 + should_stringify_to!(Int64, "x"); 302 + should_stringify_to!(UInt64, "t"); 303 + should_stringify_to!(Double, "d"); 304 + should_stringify_to!(String, "s"); 297 305 should_stringify_to!(ObjectPath, "o"); 298 - should_stringify_to!(Signature, "g"); 299 - should_stringify_to!(Variant, "v"); 306 + should_stringify_to!(Signature, "g"); 307 + should_stringify_to!(Variant, "v"); 300 308 } 301 309 302 310 #[test] ··· 313 321 should_stringify_to!(Struct(vec![Int32]), "(i)"); 314 322 should_stringify_to!(Struct(vec![Int32, String]), "(is)"); 315 323 should_stringify_to!(Struct(vec![Byte, Int32, String]), "(yis)"); 316 - should_stringify_to!(Struct(vec![Byte, Struct(vec![String, Boolean]), String]), "(y(sb)s)"); 324 + should_stringify_to!( 325 + Struct(vec![Byte, Struct(vec![String, Boolean]), String]), 326 + "(y(sb)s)" 327 + ); 317 328 } 318 329 319 330 #[test] ··· 326 337 #[test] 327 338 fn test_stringify_nested() { 328 339 use self::DbusType::*; 329 - should_stringify_to!(Array(DictEntry(String.into(), Int32.into()).into()), "a{si}"); 340 + should_stringify_to!( 341 + Array(DictEntry(String.into(), Int32.into()).into()), 342 + "a{si}" 343 + ); 330 344 should_stringify_to!( 331 345 Array( 332 346 DictEntry( 333 347 String.into(), 334 - Struct(vec![ 335 - Byte, 336 - Array(Int32.into()) 337 - ]).into() 338 - ).into() 348 + Struct(vec![Byte, Array(Int32.into())]).into() 349 + ) 350 + .into() 339 351 ), 340 352 "a{s(yai)}" 341 353 );
+108 -77
src/introspection.rs
··· 1 - use nu_protocol::{Value, record, Span}; 1 + use nu_protocol::{record, Span, Value}; 2 2 use serde::Deserialize; 3 3 4 4 macro_rules! list_to_value { 5 - ($list:expr, $span:expr) => ( 5 + ($list:expr, $span:expr) => { 6 6 Value::list($list.iter().map(|i| i.to_value($span)).collect(), $span) 7 - ) 7 + }; 8 8 } 9 9 10 10 #[derive(Debug, Clone, Deserialize, PartialEq, Eq, Default)] ··· 41 41 /// Find a method on an interface on this node, and then generate the signature of the method 42 42 /// args 43 43 pub fn get_method_args_signature(&self, interface: &str, method: &str) -> Option<String> { 44 - Some(self.get_interface(interface)?.get_method(method)?.in_signature()) 44 + Some( 45 + self.get_interface(interface)? 46 + .get_method(method)? 47 + .in_signature(), 48 + ) 45 49 } 46 50 47 51 /// Find the signature of a property on an interface on this node 48 52 pub fn get_property_signature(&self, interface: &str, property: &str) -> Option<&str> { 49 - Some(&self.get_interface(interface)?.get_property(property)?.r#type) 53 + Some( 54 + &self 55 + .get_interface(interface)? 56 + .get_property(property)? 57 + .r#type, 58 + ) 50 59 } 51 60 52 61 /// Represent the node as a nushell [Value] 53 62 pub fn to_value(&self, span: Span) -> Value { 54 - Value::record(record!{ 55 - "name" => self.name.as_ref().map(|s| Value::string(s, span)).unwrap_or_default(), 56 - "interfaces" => list_to_value!(self.interfaces, span), 57 - "children" => list_to_value!(self.children, span), 58 - }, span) 63 + Value::record( 64 + record! { 65 + "name" => self.name.as_ref().map(|s| Value::string(s, span)).unwrap_or_default(), 66 + "interfaces" => list_to_value!(self.interfaces, span), 67 + "children" => list_to_value!(self.children, span), 68 + }, 69 + span, 70 + ) 59 71 } 60 72 } 61 73 ··· 89 101 90 102 /// Represent the interface as a nushell [Value] 91 103 pub fn to_value(&self, span: Span) -> Value { 92 - Value::record(record!{ 93 - "name" => Value::string(&self.name, span), 94 - "methods" => list_to_value!(self.methods, span), 95 - "signals" => list_to_value!(self.signals, span), 96 - "properties" => list_to_value!(self.properties, span), 97 - "signals" => list_to_value!(self.signals, span), 98 - }, span) 104 + Value::record( 105 + record! { 106 + "name" => Value::string(&self.name, span), 107 + "methods" => list_to_value!(self.methods, span), 108 + "signals" => list_to_value!(self.signals, span), 109 + "properties" => list_to_value!(self.properties, span), 110 + "signals" => list_to_value!(self.signals, span), 111 + }, 112 + span, 113 + ) 99 114 } 100 115 } 101 116 ··· 112 127 impl Method { 113 128 /// Get the signature of the method args 114 129 pub fn in_signature(&self) -> String { 115 - self.args.iter() 130 + self.args 131 + .iter() 116 132 .filter(|arg| arg.direction == Direction::In) 117 133 .map(|arg| &arg.r#type[..]) 118 134 .collect() ··· 121 137 #[allow(dead_code)] 122 138 /// Get the signature of the method result 123 139 pub fn out_signature(&self) -> String { 124 - self.args.iter() 140 + self.args 141 + .iter() 125 142 .filter(|arg| arg.direction == Direction::Out) 126 143 .map(|arg| &arg.r#type[..]) 127 144 .collect() ··· 129 146 130 147 /// Represent the method as a nushell [Value] 131 148 pub fn to_value(&self, span: Span) -> Value { 132 - Value::record(record!{ 133 - "name" => Value::string(&self.name, span), 134 - "args" => list_to_value!(self.args, span), 135 - "annotations" => list_to_value!(self.annotations, span), 136 - }, span) 149 + Value::record( 150 + record! { 151 + "name" => Value::string(&self.name, span), 152 + "args" => list_to_value!(self.args, span), 153 + "annotations" => list_to_value!(self.annotations, span), 154 + }, 155 + span, 156 + ) 137 157 } 138 158 } 139 159 ··· 152 172 pub fn new( 153 173 name: impl Into<String>, 154 174 r#type: impl Into<String>, 155 - direction: Direction 175 + direction: Direction, 156 176 ) -> MethodArg { 157 177 MethodArg { 158 178 name: Some(name.into()), ··· 163 183 164 184 /// Represent the method as a nushell [Value] 165 185 pub fn to_value(&self, span: Span) -> Value { 166 - Value::record(record!{ 167 - "name" => self.name.as_ref().map(|n| Value::string(n, span)).unwrap_or_default(), 168 - "type" => Value::string(&self.r#type, span), 169 - "direction" => self.direction.to_value(span), 170 - }, span) 186 + Value::record( 187 + record! { 188 + "name" => self.name.as_ref().map(|n| Value::string(n, span)).unwrap_or_default(), 189 + "type" => Value::string(&self.r#type, span), 190 + "direction" => self.direction.to_value(span), 191 + }, 192 + span, 193 + ) 171 194 } 172 195 } 173 196 ··· 181 204 182 205 impl Direction { 183 206 /// Represent the direction as a nushell [Value] 184 - pub fn to_value(&self, span: Span) -> Value { 207 + pub fn to_value(self, span: Span) -> Value { 185 208 match self { 186 209 Direction::In => Value::string("in", span), 187 210 Direction::Out => Value::string("out", span), ··· 202 225 impl Signal { 203 226 /// Represent the signal as a nushell [Value] 204 227 pub fn to_value(&self, span: Span) -> Value { 205 - Value::record(record!{ 206 - "name" => Value::string(&self.name, span), 207 - "args" => list_to_value!(self.args, span), 208 - "annotations" => list_to_value!(self.annotations, span), 209 - }, span) 228 + Value::record( 229 + record! { 230 + "name" => Value::string(&self.name, span), 231 + "args" => list_to_value!(self.args, span), 232 + "annotations" => list_to_value!(self.annotations, span), 233 + }, 234 + span, 235 + ) 210 236 } 211 237 } 212 238 ··· 221 247 impl SignalArg { 222 248 /// Represent the argument as a nushell [Value] 223 249 pub fn to_value(&self, span: Span) -> Value { 224 - Value::record(record!{ 225 - "name" => self.name.as_ref().map(|n| Value::string(n, span)).unwrap_or_default(), 226 - "type" => Value::string(&self.r#type, span), 227 - }, span) 250 + Value::record( 251 + record! { 252 + "name" => self.name.as_ref().map(|n| Value::string(n, span)).unwrap_or_default(), 253 + "type" => Value::string(&self.r#type, span), 254 + }, 255 + span, 256 + ) 228 257 } 229 258 } 230 259 ··· 241 270 impl Property { 242 271 /// Represent the property as a nushell [Value] 243 272 pub fn to_value(&self, span: Span) -> Value { 244 - Value::record(record!{ 245 - "name" => Value::string(&self.name, span), 246 - "type" => Value::string(&self.r#type, span), 247 - "args" => self.access.to_value(span), 248 - "annotations" => list_to_value!(self.annotations, span), 249 - }, span) 273 + Value::record( 274 + record! { 275 + "name" => Value::string(&self.name, span), 276 + "type" => Value::string(&self.r#type, span), 277 + "args" => self.access.to_value(span), 278 + "annotations" => list_to_value!(self.annotations, span), 279 + }, 280 + span, 281 + ) 250 282 } 251 283 } 252 284 ··· 279 311 impl Annotation { 280 312 #[cfg(test)] 281 313 pub fn new(name: impl Into<String>, value: impl Into<String>) -> Annotation { 282 - Annotation { name: name.into(), value: value.into() } 314 + Annotation { 315 + name: name.into(), 316 + value: value.into(), 317 + } 283 318 } 284 319 285 320 /// Represent the annotation as a nushell [Value] 286 321 pub fn to_value(&self, span: Span) -> Value { 287 - Value::record(record!{ 288 - "name" => Value::string(&self.name, span), 289 - "value" => Value::string(&self.value, span), 290 - }, span) 322 + Value::record( 323 + record! { 324 + "name" => Value::string(&self.name, span), 325 + "value" => Value::string(&self.value, span), 326 + }, 327 + span, 328 + ) 291 329 } 292 330 } 293 331 ··· 305 343 MethodArg::new("bar", "as", Direction::In), 306 344 MethodArg::new("baz", "a{us}", Direction::Out), 307 345 ], 308 - annotations: vec![ 309 - Annotation::new("org.freedesktop.DBus.Deprecated", "true"), 310 - ], 346 + annotations: vec![Annotation::new("org.freedesktop.DBus.Deprecated", "true")], 311 347 }, 312 348 Method { 313 349 name: "Bazify".into(), ··· 320 356 }, 321 357 Method { 322 358 name: "Mogrify".into(), 323 - args: vec![ 324 - MethodArg::new("bar", "(iiav)", Direction::In), 325 - ], 326 - annotations: vec![] 327 - }, 328 - ], 329 - signals: vec![ 330 - Signal { 331 - name: "Changed".into(), 332 - args: vec![ 333 - SignalArg { name: Some("new_value".into()), r#type: "b".into() }, 334 - ], 335 - annotations: vec![] 336 - }, 337 - ], 338 - properties: vec![ 339 - Property { 340 - name: "Bar".into(), 341 - r#type: "y".into(), 342 - access: Access::ReadWrite, 359 + args: vec![MethodArg::new("bar", "(iiav)", Direction::In)], 343 360 annotations: vec![], 344 - } 361 + }, 345 362 ], 346 - annotations: vec![] 363 + signals: vec![Signal { 364 + name: "Changed".into(), 365 + args: vec![SignalArg { 366 + name: Some("new_value".into()), 367 + r#type: "b".into(), 368 + }], 369 + annotations: vec![], 370 + }], 371 + properties: vec![Property { 372 + name: "Bar".into(), 373 + r#type: "y".into(), 374 + access: Access::ReadWrite, 375 + annotations: vec![], 376 + }], 377 + annotations: vec![], 347 378 }], 348 379 children: vec![ 349 380 Node::with_name("child_of_sample_object"), 350 381 Node::with_name("another_child_of_sample_object"), 351 - ] 382 + ], 352 383 } 353 384 } 354 385
+53 -31
src/main.rs
··· 1 - use nu_plugin::{serve_plugin, MsgPackSerializer, Plugin, EvaluatedCall, LabeledError}; 2 - use nu_protocol::{PluginSignature, Value, SyntaxShape, PluginExample, Span, Type}; 1 + use nu_plugin::{serve_plugin, EvaluatedCall, LabeledError, MsgPackSerializer, Plugin}; 2 + use nu_protocol::{PluginExample, PluginSignature, Span, SyntaxShape, Type, Value}; 3 3 4 + mod client; 4 5 mod config; 5 - mod client; 6 6 mod convert; 7 7 mod dbus_type; 8 8 mod introspection; 9 9 mod pattern; 10 10 11 - use config::*; 12 11 use client::*; 12 + use config::*; 13 13 14 14 use crate::pattern::Pattern; 15 15 ··· 23 23 impl Plugin for NuPluginDbus { 24 24 fn signature(&self) -> Vec<PluginSignature> { 25 25 macro_rules! str { 26 - ($s:expr) => (Value::string($s, Span::unknown())) 26 + ($s:expr) => { 27 + Value::string($s, Span::unknown()) 28 + }; 27 29 } 28 30 vec![ 29 31 PluginSignature::build("dbus") 30 - .is_dbus_command() 32 + .dbus_command() 31 33 .usage("Commands for interacting with D-Bus"), 32 34 PluginSignature::build("dbus introspect") 33 - .is_dbus_command() 35 + .dbus_command() 34 36 .accepts_dbus_client_options() 35 37 .accepts_timeout() 36 38 .usage("Introspect a D-Bus object") ··· 65 67 }, 66 68 ]), 67 69 PluginSignature::build("dbus call") 68 - .is_dbus_command() 70 + .dbus_command() 69 71 .accepts_dbus_client_options() 70 72 .accepts_timeout() 71 73 .usage("Call a method and get its response") ··· 108 110 }, 109 111 ]), 110 112 PluginSignature::build("dbus get") 111 - .is_dbus_command() 113 + .dbus_command() 112 114 .accepts_dbus_client_options() 113 115 .accepts_timeout() 114 116 .usage("Get a D-Bus property") ··· 139 141 }, 140 142 ]), 141 143 PluginSignature::build("dbus get-all") 142 - .is_dbus_command() 144 + .dbus_command() 143 145 .accepts_dbus_client_options() 144 146 .accepts_timeout() 145 147 .usage("Get all D-Bus properties for the given object") ··· 165 167 }, 166 168 ]), 167 169 PluginSignature::build("dbus set") 168 - .is_dbus_command() 170 + .dbus_command() 169 171 .accepts_dbus_client_options() 170 172 .accepts_timeout() 171 173 .usage("Set a D-Bus property") ··· 196 198 }, 197 199 ]), 198 200 PluginSignature::build("dbus list") 199 - .is_dbus_command() 201 + .dbus_command() 200 202 .accepts_dbus_client_options() 201 203 .accepts_timeout() 202 204 .usage("List all available connection names on the bus") ··· 244 246 "dbus" => Err(LabeledError { 245 247 label: "The `dbus` command requires a subcommand".into(), 246 248 msg: "add --help to see subcommands".into(), 247 - span: Some(call.head) 249 + span: Some(call.head), 248 250 }), 249 251 250 252 "dbus introspect" => self.introspect(call), ··· 257 259 _ => Err(LabeledError { 258 260 label: "Plugin invoked with unknown command name".into(), 259 261 msg: "unknown command".into(), 260 - span: Some(call.head) 261 - }) 262 + span: Some(call.head), 263 + }), 262 264 } 263 265 } 264 266 } 265 267 266 268 /// For conveniently adding the base options to a dbus command 267 269 trait DbusSignatureUtilExt { 268 - fn is_dbus_command(self) -> Self; 270 + fn dbus_command(self) -> Self; 269 271 fn accepts_dbus_client_options(self) -> Self; 270 272 fn accepts_timeout(self) -> Self; 271 273 } 272 274 273 275 impl DbusSignatureUtilExt for PluginSignature { 274 - fn is_dbus_command(self) -> Self { 276 + fn dbus_command(self) -> Self { 275 277 self.search_terms(vec!["dbus".into()]) 276 278 .category(nu_protocol::Category::Platform) 277 279 } ··· 279 281 fn accepts_dbus_client_options(self) -> Self { 280 282 self.switch("session", "Send to the session message bus (default)", None) 281 283 .switch("system", "Send to the system message bus", None) 282 - .switch("started", "Send to the bus that started this process, if applicable", None) 283 - .named("bus", SyntaxShape::String, "Send to the bus server at the given address", None) 284 - .named("peer", SyntaxShape::String, 284 + .switch( 285 + "started", 286 + "Send to the bus that started this process, if applicable", 287 + None, 288 + ) 289 + .named( 290 + "bus", 291 + SyntaxShape::String, 292 + "Send to the bus server at the given address", 293 + None, 294 + ) 295 + .named( 296 + "peer", 297 + SyntaxShape::String, 285 298 "Send to a non-bus D-Bus server at the given address. \ 286 299 Will not call the Hello method on initialization.", 287 - None) 300 + None, 301 + ) 288 302 } 289 303 290 304 fn accepts_timeout(self) -> Self { 291 - self.named("timeout", SyntaxShape::Duration, "How long to wait for a response", None) 305 + self.named( 306 + "timeout", 307 + SyntaxShape::Duration, 308 + "How long to wait for a response", 309 + None, 310 + ) 292 311 } 293 312 } 294 313 ··· 296 315 fn introspect(&self, call: &EvaluatedCall) -> Result<Value, LabeledError> { 297 316 let config = DbusClientConfig::try_from(call)?; 298 317 let dbus = DbusClient::new(config)?; 299 - let node = dbus.introspect( 300 - &call.get_flag("dest")?.unwrap(), 301 - &call.req(0)?, 302 - )?; 318 + let node = dbus.introspect(&call.get_flag("dest")?.unwrap(), &call.req(0)?)?; 303 319 Ok(node.to_value(call.head)) 304 320 } 305 321 ··· 312 328 &call.req(1)?, 313 329 &call.req(2)?, 314 330 call.get_flag("signature")?.as_ref(), 315 - &call.positional[3..] 331 + &call.positional[3..], 316 332 )?; 317 333 318 334 let flatten = !call.get_flag::<bool>("no-flatten")?.unwrap_or(false); ··· 322 338 match values.len() { 323 339 0 if flatten => Ok(Value::nothing(call.head)), 324 340 1 if flatten => Ok(values.into_iter().nth(0).unwrap()), 325 - _ => Ok(Value::list(values, call.head)) 341 + _ => Ok(Value::list(values, call.head)), 326 342 } 327 343 } 328 344 ··· 364 380 fn list(&self, call: &EvaluatedCall) -> Result<Value, LabeledError> { 365 381 let config = DbusClientConfig::try_from(call)?; 366 382 let dbus = DbusClient::new(config)?; 367 - let pattern = call.opt::<String>(0)?.map(|pat| Pattern::new(&pat, Some('.'))); 383 + let pattern = call 384 + .opt::<String>(0)? 385 + .map(|pat| Pattern::new(&pat, Some('.'))); 368 386 let result = dbus.list(pattern.as_ref())?; 369 387 Ok(Value::list( 370 - result.into_iter().map(|s| Value::string(s, call.head)).collect(), 371 - call.head)) 388 + result 389 + .into_iter() 390 + .map(|s| Value::string(s, call.head)) 391 + .collect(), 392 + call.head, 393 + )) 372 394 } 373 395 }
+208 -125
src/pattern.rs
··· 17 17 let mut tokens = vec![]; 18 18 for ch in pattern.chars() { 19 19 match ch { 20 - '*' => 20 + '*' => { 21 21 if tokens.last() == Some(&PatternToken::OneWildcard) { 22 22 *tokens.last_mut().unwrap() = PatternToken::ManyWildcard; 23 23 } else { 24 24 tokens.push(PatternToken::OneWildcard); 25 - }, 26 - '?' => 27 - tokens.push(PatternToken::AnyChar), 28 - _ => 29 - match tokens.last_mut() { 30 - Some(PatternToken::Exact(ref mut s)) => s.push(ch), 31 - _ => tokens.push(PatternToken::Exact(ch.into())), 32 - }, 25 + } 26 + } 27 + '?' => tokens.push(PatternToken::AnyChar), 28 + _ => match tokens.last_mut() { 29 + Some(PatternToken::Exact(ref mut s)) => s.push(ch), 30 + _ => tokens.push(PatternToken::Exact(ch.into())), 31 + }, 33 32 } 34 33 } 35 34 Pattern { separator, tokens } ··· 57 56 MatchState::Precise => { 58 57 // Can't possibly match 59 58 return false; 60 - }, 59 + } 61 60 MatchState::ScanAhead { stop_at_separator } => { 62 61 if search_str.is_empty() { 63 62 // End of input, can't match 64 63 return false; 65 64 } 66 - if stop_at_separator && 67 - self.separator.is_some_and(|sep| search_str.starts_with(sep)) { 65 + if stop_at_separator 66 + && self 67 + .separator 68 + .is_some_and(|sep| search_str.starts_with(sep)) 69 + { 68 70 // Found the separator. Consume a char and revert to precise 69 71 // mode 70 72 search_str = &search_str[1..]; ··· 76 78 } 77 79 } 78 80 } 79 - }, 81 + } 80 82 PatternToken::OneWildcard => { 81 83 // Set the mode to ScanAhead, stopping at separator 82 - state = MatchState::ScanAhead { stop_at_separator: true }; 84 + state = MatchState::ScanAhead { 85 + stop_at_separator: true, 86 + }; 83 87 tokens = &tokens[1..]; 84 - }, 88 + } 85 89 PatternToken::ManyWildcard => { 86 90 // Set the mode to ScanAhead, ignoring separator 87 - state = MatchState::ScanAhead { stop_at_separator: false }; 91 + state = MatchState::ScanAhead { 92 + stop_at_separator: false, 93 + }; 88 94 tokens = &tokens[1..]; 89 - }, 95 + } 90 96 PatternToken::AnyChar => { 91 97 if !search_str.is_empty() { 92 98 // Take a char from the search str and continue ··· 96 102 // End of input 97 103 return false; 98 104 } 99 - }, 105 + } 100 106 } 101 107 } 102 - #[cfg(test)] { 103 - println!("end, state={:?}, search_str={:?}, tokens={:?}", state, search_str, tokens); 108 + #[cfg(test)] 109 + { 110 + println!( 111 + "end, state={:?}, search_str={:?}, tokens={:?}", 112 + state, search_str, tokens 113 + ); 104 114 } 105 115 if !search_str.is_empty() { 106 116 // If the search str is not empty at the end ··· 108 118 // We didn't end with a wildcard, so this is a fail 109 119 MatchState::Precise => false, 110 120 // This could be a match as long as the separator isn't contained in the remainder 111 - MatchState::ScanAhead { stop_at_separator: true } => 121 + MatchState::ScanAhead { 122 + stop_at_separator: true, 123 + } => { 112 124 if let Some(separator) = self.separator { 113 125 !search_str.contains(separator) 114 126 } else { 115 127 // No separator specified, so this is a success 116 128 true 117 - }, 129 + } 130 + } 118 131 // Always a success, no matter what remains 119 - MatchState::ScanAhead { stop_at_separator: false } => true, 132 + MatchState::ScanAhead { 133 + stop_at_separator: false, 134 + } => true, 120 135 } 121 136 } else { 122 137 // The match has succeeded - there is nothing more to match ··· 129 144 fn test_pattern_new() { 130 145 assert_eq!( 131 146 Pattern::new("", Some('/')), 132 - Pattern { separator: Some('/'), tokens: vec![] } 147 + Pattern { 148 + separator: Some('/'), 149 + tokens: vec![] 150 + } 133 151 ); 134 152 assert_eq!( 135 153 Pattern::new("", None), 136 - Pattern { separator: None, tokens: vec![] } 154 + Pattern { 155 + separator: None, 156 + tokens: vec![] 157 + } 137 158 ); 138 159 assert_eq!( 139 160 Pattern::new("org.freedesktop.DBus", Some('.')), 140 - Pattern { separator: Some('.'), tokens: vec![ 141 - PatternToken::Exact("org.freedesktop.DBus".into()), 142 - ] } 161 + Pattern { 162 + separator: Some('.'), 163 + tokens: vec![PatternToken::Exact("org.freedesktop.DBus".into()),] 164 + } 143 165 ); 144 166 assert_eq!( 145 167 Pattern::new("*", Some('.')), 146 - Pattern { separator: Some('.'), tokens: vec![ 147 - PatternToken::OneWildcard, 148 - ] } 168 + Pattern { 169 + separator: Some('.'), 170 + tokens: vec![PatternToken::OneWildcard,] 171 + } 149 172 ); 150 173 assert_eq!( 151 174 Pattern::new("**", Some('.')), 152 - Pattern { separator: Some('.'), tokens: vec![ 153 - PatternToken::ManyWildcard, 154 - ] } 175 + Pattern { 176 + separator: Some('.'), 177 + tokens: vec![PatternToken::ManyWildcard,] 178 + } 155 179 ); 156 180 assert_eq!( 157 181 Pattern::new("?", Some('.')), 158 - Pattern { separator: Some('.'), tokens: vec![ 159 - PatternToken::AnyChar, 160 - ] } 182 + Pattern { 183 + separator: Some('.'), 184 + tokens: vec![PatternToken::AnyChar,] 185 + } 161 186 ); 162 187 assert_eq!( 163 188 Pattern::new("org.freedesktop.*", Some('.')), 164 - Pattern { separator: Some('.'), tokens: vec![ 165 - PatternToken::Exact("org.freedesktop.".into()), 166 - PatternToken::OneWildcard, 167 - ] } 189 + Pattern { 190 + separator: Some('.'), 191 + tokens: vec![ 192 + PatternToken::Exact("org.freedesktop.".into()), 193 + PatternToken::OneWildcard, 194 + ] 195 + } 168 196 ); 169 197 assert_eq!( 170 198 Pattern::new("org.freedesktop.**", Some('.')), 171 - Pattern { separator: Some('.'), tokens: vec![ 172 - PatternToken::Exact("org.freedesktop.".into()), 173 - PatternToken::ManyWildcard, 174 - ] } 199 + Pattern { 200 + separator: Some('.'), 201 + tokens: vec![ 202 + PatternToken::Exact("org.freedesktop.".into()), 203 + PatternToken::ManyWildcard, 204 + ] 205 + } 175 206 ); 176 207 assert_eq!( 177 208 Pattern::new("org.*.DBus", Some('.')), 178 - Pattern { separator: Some('.'), tokens: vec![ 179 - PatternToken::Exact("org.".into()), 180 - PatternToken::OneWildcard, 181 - PatternToken::Exact(".DBus".into()), 182 - ] } 209 + Pattern { 210 + separator: Some('.'), 211 + tokens: vec![ 212 + PatternToken::Exact("org.".into()), 213 + PatternToken::OneWildcard, 214 + PatternToken::Exact(".DBus".into()), 215 + ] 216 + } 183 217 ); 184 218 assert_eq!( 185 219 Pattern::new("org.**.DBus", Some('.')), 186 - Pattern { separator: Some('.'), tokens: vec![ 187 - PatternToken::Exact("org.".into()), 188 - PatternToken::ManyWildcard, 189 - PatternToken::Exact(".DBus".into()), 190 - ] } 220 + Pattern { 221 + separator: Some('.'), 222 + tokens: vec![ 223 + PatternToken::Exact("org.".into()), 224 + PatternToken::ManyWildcard, 225 + PatternToken::Exact(".DBus".into()), 226 + ] 227 + } 191 228 ); 192 229 assert_eq!( 193 230 Pattern::new("org.**.?Bus", Some('.')), 194 - Pattern { separator: Some('.'), tokens: vec![ 195 - PatternToken::Exact("org.".into()), 196 - PatternToken::ManyWildcard, 197 - PatternToken::Exact(".".into()), 198 - PatternToken::AnyChar, 199 - PatternToken::Exact("Bus".into()), 200 - ] } 231 + Pattern { 232 + separator: Some('.'), 233 + tokens: vec![ 234 + PatternToken::Exact("org.".into()), 235 + PatternToken::ManyWildcard, 236 + PatternToken::Exact(".".into()), 237 + PatternToken::AnyChar, 238 + PatternToken::Exact("Bus".into()), 239 + ] 240 + } 201 241 ); 202 242 assert_eq!( 203 243 Pattern::new("org.free*top", Some('.')), 204 - Pattern { separator: Some('.'), tokens: vec![ 205 - PatternToken::Exact("org.free".into()), 206 - PatternToken::OneWildcard, 207 - PatternToken::Exact("top".into()), 208 - ] } 244 + Pattern { 245 + separator: Some('.'), 246 + tokens: vec![ 247 + PatternToken::Exact("org.free".into()), 248 + PatternToken::OneWildcard, 249 + PatternToken::Exact("top".into()), 250 + ] 251 + } 209 252 ); 210 253 assert_eq!( 211 254 Pattern::new("org.free**top", Some('.')), 212 - Pattern { separator: Some('.'), tokens: vec![ 213 - PatternToken::Exact("org.free".into()), 214 - PatternToken::ManyWildcard, 215 - PatternToken::Exact("top".into()), 216 - ] } 255 + Pattern { 256 + separator: Some('.'), 257 + tokens: vec![ 258 + PatternToken::Exact("org.free".into()), 259 + PatternToken::ManyWildcard, 260 + PatternToken::Exact("top".into()), 261 + ] 262 + } 217 263 ); 218 264 assert_eq!( 219 265 Pattern::new("org.**top", Some('.')), 220 - Pattern { separator: Some('.'), tokens: vec![ 221 - PatternToken::Exact("org.".into()), 222 - PatternToken::ManyWildcard, 223 - PatternToken::Exact("top".into()), 224 - ] } 266 + Pattern { 267 + separator: Some('.'), 268 + tokens: vec![ 269 + PatternToken::Exact("org.".into()), 270 + PatternToken::ManyWildcard, 271 + PatternToken::Exact("top".into()), 272 + ] 273 + } 225 274 ); 226 275 assert_eq!( 227 276 Pattern::new("**top", Some('.')), 228 - Pattern { separator: Some('.'), tokens: vec![ 229 - PatternToken::ManyWildcard, 230 - PatternToken::Exact("top".into()), 231 - ] } 277 + Pattern { 278 + separator: Some('.'), 279 + tokens: vec![ 280 + PatternToken::ManyWildcard, 281 + PatternToken::Exact("top".into()), 282 + ] 283 + } 232 284 ); 233 285 assert_eq!( 234 286 Pattern::new("org.free**", Some('.')), 235 - Pattern { separator: Some('.'), tokens: vec![ 236 - PatternToken::Exact("org.free".into()), 237 - PatternToken::ManyWildcard, 238 - ] } 287 + Pattern { 288 + separator: Some('.'), 289 + tokens: vec![ 290 + PatternToken::Exact("org.free".into()), 291 + PatternToken::ManyWildcard, 292 + ] 293 + } 239 294 ); 240 295 } 241 296 242 297 #[test] 243 298 fn test_pattern_is_match_empty() { 244 - let pat = Pattern { separator: Some('.'), tokens: vec![] }; 299 + let pat = Pattern { 300 + separator: Some('.'), 301 + tokens: vec![], 302 + }; 245 303 assert!(pat.is_match("")); 246 304 assert!(!pat.is_match("anystring")); 247 305 assert!(!pat.is_match("anystring.anyotherstring")); ··· 249 307 250 308 #[test] 251 309 fn test_pattern_is_match_exact() { 252 - let pat = Pattern { separator: Some('.'), tokens: vec![ 253 - PatternToken::Exact("specific".into()), 254 - ] }; 310 + let pat = Pattern { 311 + separator: Some('.'), 312 + tokens: vec![PatternToken::Exact("specific".into())], 313 + }; 255 314 assert!(pat.is_match("specific")); 256 315 assert!(!pat.is_match("")); 257 316 assert!(!pat.is_match("specifi")); ··· 260 319 261 320 #[test] 262 321 fn test_pattern_is_match_one_wildcard() { 263 - let pat = Pattern { separator: Some('.'), tokens: vec![ 264 - PatternToken::Exact("foo.".into()), 265 - PatternToken::OneWildcard, 266 - PatternToken::Exact(".baz".into()), 267 - ] }; 322 + let pat = Pattern { 323 + separator: Some('.'), 324 + tokens: vec![ 325 + PatternToken::Exact("foo.".into()), 326 + PatternToken::OneWildcard, 327 + PatternToken::Exact(".baz".into()), 328 + ], 329 + }; 268 330 assert!(pat.is_match("foo.bar.baz")); 269 331 assert!(pat.is_match("foo.grok.baz")); 270 332 assert!(pat.is_match("foo..baz")); ··· 277 339 278 340 #[test] 279 341 fn test_pattern_is_match_one_wildcard_at_end() { 280 - let pat = Pattern { separator: Some('.'), tokens: vec![ 281 - PatternToken::Exact("foo.".into()), 282 - PatternToken::OneWildcard, 283 - ] }; 342 + let pat = Pattern { 343 + separator: Some('.'), 344 + tokens: vec![ 345 + PatternToken::Exact("foo.".into()), 346 + PatternToken::OneWildcard, 347 + ], 348 + }; 284 349 assert!(pat.is_match("foo.bar")); 285 350 assert!(pat.is_match("foo.grok")); 286 351 assert!(pat.is_match("foo.")); ··· 292 357 293 358 #[test] 294 359 fn test_pattern_is_match_one_wildcard_at_start() { 295 - let pat = Pattern { separator: Some('.'), tokens: vec![ 296 - PatternToken::OneWildcard, 297 - PatternToken::Exact(".bar".into()), 298 - ] }; 360 + let pat = Pattern { 361 + separator: Some('.'), 362 + tokens: vec![ 363 + PatternToken::OneWildcard, 364 + PatternToken::Exact(".bar".into()), 365 + ], 366 + }; 299 367 assert!(pat.is_match("foo.bar")); 300 368 assert!(pat.is_match("grok.bar")); 301 369 assert!(pat.is_match(".bar")); ··· 307 375 308 376 #[test] 309 377 fn test_pattern_is_match_one_wildcard_no_separator() { 310 - let pat = Pattern { separator: None, tokens: vec![ 311 - PatternToken::Exact("foo.".into()), 312 - PatternToken::OneWildcard, 313 - PatternToken::Exact(".baz".into()), 314 - ] }; 378 + let pat = Pattern { 379 + separator: None, 380 + tokens: vec![ 381 + PatternToken::Exact("foo.".into()), 382 + PatternToken::OneWildcard, 383 + PatternToken::Exact(".baz".into()), 384 + ], 385 + }; 315 386 assert!(pat.is_match("foo.bar.baz")); 316 387 assert!(pat.is_match("foo.grok.baz")); 317 388 assert!(pat.is_match("foo..baz")); ··· 325 396 326 397 #[test] 327 398 fn test_pattern_is_match_many_wildcard() { 328 - let pat = Pattern { separator: Some('.'), tokens: vec![ 329 - PatternToken::Exact("foo.".into()), 330 - PatternToken::ManyWildcard, 331 - PatternToken::Exact(".baz".into()), 332 - ] }; 399 + let pat = Pattern { 400 + separator: Some('.'), 401 + tokens: vec![ 402 + PatternToken::Exact("foo.".into()), 403 + PatternToken::ManyWildcard, 404 + PatternToken::Exact(".baz".into()), 405 + ], 406 + }; 333 407 assert!(pat.is_match("foo.bar.baz")); 334 408 assert!(pat.is_match("foo.grok.baz")); 335 409 assert!(pat.is_match("foo..baz")); ··· 343 417 344 418 #[test] 345 419 fn test_pattern_is_match_many_wildcard_at_end() { 346 - let pat = Pattern { separator: Some('.'), tokens: vec![ 347 - PatternToken::Exact("foo.".into()), 348 - PatternToken::ManyWildcard, 349 - ] }; 420 + let pat = Pattern { 421 + separator: Some('.'), 422 + tokens: vec![ 423 + PatternToken::Exact("foo.".into()), 424 + PatternToken::ManyWildcard, 425 + ], 426 + }; 350 427 assert!(pat.is_match("foo.bar")); 351 428 assert!(pat.is_match("foo.grok")); 352 429 assert!(pat.is_match("foo.")); ··· 358 435 359 436 #[test] 360 437 fn test_pattern_is_match_many_wildcard_at_start() { 361 - let pat = Pattern { separator: Some('.'), tokens: vec![ 362 - PatternToken::ManyWildcard, 363 - PatternToken::Exact(".bar".into()), 364 - ] }; 438 + let pat = Pattern { 439 + separator: Some('.'), 440 + tokens: vec![ 441 + PatternToken::ManyWildcard, 442 + PatternToken::Exact(".bar".into()), 443 + ], 444 + }; 365 445 assert!(pat.is_match("foo.bar")); 366 446 assert!(pat.is_match("grok.bar")); 367 447 assert!(pat.is_match("should.match.bar")); ··· 373 453 374 454 #[test] 375 455 fn test_pattern_is_match_any_char() { 376 - let pat = Pattern { separator: Some('.'), tokens: vec![ 377 - PatternToken::Exact("fo".into()), 378 - PatternToken::AnyChar, 379 - PatternToken::Exact(".baz".into()), 380 - ] }; 456 + let pat = Pattern { 457 + separator: Some('.'), 458 + tokens: vec![ 459 + PatternToken::Exact("fo".into()), 460 + PatternToken::AnyChar, 461 + PatternToken::Exact(".baz".into()), 462 + ], 463 + }; 381 464 assert!(pat.is_match("foo.baz")); 382 465 assert!(pat.is_match("foe.baz")); 383 466 assert!(pat.is_match("foi.baz"));