#[cfg(test)] mod tests; use crate::strutils::ReplaceAction; use crate::Str; use nu_errors::ShellError; use nu_plugin::Plugin; use nu_protocol::{ CallInfo, Primitive, ReturnSuccess, ReturnValue, ShellTypeName, Signature, SyntaxShape, UntaggedValue, Value, }; use nu_value_ext::ValueExt; impl Plugin for Str { fn config(&mut self) -> Result { Ok(Signature::build("str") .desc("Apply string function. Optional use the column of a table") .switch("capitalize", "capitalizes the string", Some('c')) .switch("downcase", "convert string to lowercase", Some('d')) .switch("upcase", "convert string to uppercase", Some('U')) .switch("to-int", "convert string to integer", Some('i')) .switch("trim", "trims the string", Some('t')) .named( "replace", SyntaxShape::String, "replaces the string", Some('r'), ) .named( "find-replace", SyntaxShape::Any, "finds and replaces [pattern replacement]", Some('f'), ) .named( "substring", SyntaxShape::String, "convert string to portion of original, requires \"start,end\"", Some('s'), ) .named( "to-date-time", SyntaxShape::String, "Convert string to Date/Time", Some('D'), ) .rest(SyntaxShape::ColumnPath, "the column(s) to convert") .filter()) } fn begin_filter(&mut self, call_info: CallInfo) -> Result, ShellError> { let args = call_info.args; if args.has("trim") { self.for_trim(); } if args.has("capitalize") { self.for_capitalize(); } if args.has("downcase") { self.for_downcase(); } if args.has("upcase") { self.for_upcase(); } if args.has("to-int") { self.for_to_int(); } if args.has("substring") { if let Some(start_end) = args.get("substring") { match start_end { Value { value: UntaggedValue::Primitive(Primitive::String(s)), .. } => { self.for_substring(s.to_string())?; } _ => { return Err(ShellError::labeled_error( "Unrecognized type in params", start_end.type_name(), &start_end.tag, )) } } } } if args.has("replace") { if let Some(Value { value: UntaggedValue::Primitive(Primitive::String(replacement)), .. }) = args.get("replace") { self.for_replace(ReplaceAction::Direct(replacement.clone())); } } if args.has("find-replace") { if let Some(Value { value: UntaggedValue::Table(arguments), tag, }) = args.get("find-replace") { self.for_replace(ReplaceAction::FindAndReplace( arguments .get(0) .ok_or_else(|| { ShellError::labeled_error( "expected file and replace strings eg) [find replace]", "missing find-replace values", tag, ) })? .as_string()?, arguments .get(1) .ok_or_else(|| { ShellError::labeled_error( "expected file and replace strings eg) [find replace]", "missing find-replace values", tag, ) })? .as_string()?, )); } } if let Some(possible_field) = args.nth(0) { let possible_field = possible_field.as_column_path()?; self.for_field(possible_field); } if let Some(dt) = args.get("to-date-time") { let dt = dt.as_string()?; self.for_date_time(dt); } match &self.error { Some(reason) => Err(ShellError::untagged_runtime_error(format!( "{}: {}", reason, Str::usage() ))), None => Ok(vec![]), } } fn filter(&mut self, input: Value) -> Result, ShellError> { Ok(vec![ReturnSuccess::value(self.strutils(input)?)]) } }