1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
use log::trace; use nu_errors::{CoerceInto, ShellError}; use nu_protocol::{Primitive, SpannedTypeName, UntaggedValue, Value}; use nu_source::{Tagged, TaggedItem}; pub trait ExtractType: Sized { fn extract(value: &Value) -> Result<Self, ShellError>; } impl<T: ExtractType> ExtractType for Tagged<T> { fn extract(value: &Value) -> Result<Tagged<T>, ShellError> { let name = std::any::type_name::<T>(); trace!("<Tagged> Extracting {:?} for Tagged<{}>", value, name); Ok(T::extract(value)?.tagged(value.tag())) } } impl ExtractType for bool { fn extract(value: &Value) -> Result<bool, ShellError> { trace!("Extracting {:?} for bool", value); match &value { Value { value: UntaggedValue::Primitive(Primitive::Boolean(b)), .. } => Ok(*b), other => Err(ShellError::type_error("Boolean", other.spanned_type_name())), } } } impl ExtractType for std::path::PathBuf { fn extract(value: &Value) -> Result<std::path::PathBuf, ShellError> { trace!("Extracting {:?} for PathBuf", value); match &value { Value { value: UntaggedValue::Primitive(Primitive::FilePath(p)), .. } => Ok(p.clone()), other => Err(ShellError::type_error("Path", other.spanned_type_name())), } } } impl ExtractType for i64 { fn extract(value: &Value) -> Result<i64, ShellError> { trace!("Extracting {:?} for i64", value); match &value { &Value { value: UntaggedValue::Primitive(Primitive::Int(int)), .. } => Ok(int.tagged(&value.tag).coerce_into("converting to i64")?), other => Err(ShellError::type_error("Integer", other.spanned_type_name())), } } } impl ExtractType for u64 { fn extract(value: &Value) -> Result<u64, ShellError> { trace!("Extracting {:?} for u64", value); match &value { &Value { value: UntaggedValue::Primitive(Primitive::Int(int)), .. } => Ok(int.tagged(&value.tag).coerce_into("converting to u64")?), other => Err(ShellError::type_error("Integer", other.spanned_type_name())), } } } impl ExtractType for String { fn extract(value: &Value) -> Result<String, ShellError> { trace!("Extracting {:?} for String", value); match value { Value { value: UntaggedValue::Primitive(Primitive::String(string)), .. } => Ok(string.clone()), other => Err(ShellError::type_error("String", other.spanned_type_name())), } } }