nushell/src/object/types.rs

181 lines
4.8 KiB
Rust
Raw Normal View History

2019-07-06 00:08:58 +02:00
use crate::object::base as value;
use crate::parser::hir;
use crate::prelude::*;
use derive_new::new;
2019-07-08 18:44:53 +02:00
use serde_derive::Deserialize;
2019-07-15 23:16:27 +02:00
use std::path::PathBuf;
2019-05-10 18:59:12 +02:00
2019-07-06 00:08:58 +02:00
pub trait Type: std::fmt::Debug + Send {
2019-07-08 18:44:53 +02:00
type Extractor: ExtractType;
2019-07-06 00:08:58 +02:00
fn name(&self) -> &'static str;
}
2019-07-08 18:44:53 +02:00
pub trait ExtractType: Sized {
2019-08-01 03:58:42 +02:00
fn extract(value: &Tagged<Value>) -> Result<Self, ShellError>;
fn check(value: &'value Tagged<Value>) -> Result<&'value Tagged<Value>, ShellError>;
2019-07-15 23:16:27 +02:00
fn syntax_type() -> hir::SyntaxType {
hir::SyntaxType::Any
}
}
2019-08-01 03:58:42 +02:00
impl<T: ExtractType> ExtractType for Tagged<T> {
fn extract(value: &Tagged<Value>) -> Result<Tagged<T>, ShellError> {
Ok(T::extract(value)?.simple_spanned(value.span()))
2019-07-15 23:16:27 +02:00
}
2019-08-01 03:58:42 +02:00
fn check(value: &'value Tagged<Value>) -> Result<&'value Tagged<Value>, ShellError> {
2019-07-15 23:16:27 +02:00
T::check(value)
}
fn syntax_type() -> hir::SyntaxType {
T::syntax_type()
}
2019-07-06 00:08:58 +02:00
}
#[derive(Debug, Deserialize, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, new)]
pub struct Any;
impl Type for Any {
2019-08-01 03:58:42 +02:00
type Extractor = Tagged<Value>;
2019-07-08 18:44:53 +02:00
2019-07-06 00:08:58 +02:00
fn name(&self) -> &'static str {
"Any"
}
2019-07-08 18:44:53 +02:00
}
2019-08-01 03:58:42 +02:00
impl ExtractType for Tagged<Value> {
fn extract(value: &Tagged<Value>) -> Result<Self, ShellError> {
2019-07-08 18:44:53 +02:00
Ok(value.clone())
}
2019-08-01 03:58:42 +02:00
fn check(value: &'value Tagged<Value>) -> Result<&'value Tagged<Value>, ShellError> {
2019-07-06 00:08:58 +02:00
Ok(value)
}
}
2019-07-15 23:16:27 +02:00
impl ExtractType for std::path::PathBuf {
fn syntax_type() -> hir::SyntaxType {
hir::SyntaxType::Path
}
2019-08-01 03:58:42 +02:00
fn extract(value: &'a Tagged<Value>) -> Result<std::path::PathBuf, ShellError> {
2019-07-15 23:16:27 +02:00
match &value {
2019-08-01 03:58:42 +02:00
Tagged {
2019-07-15 23:16:27 +02:00
item: Value::Primitive(Primitive::String(p)),
2019-07-16 09:08:35 +02:00
..
2019-07-15 23:16:27 +02:00
} => Ok(PathBuf::from(p)),
2019-08-01 03:58:42 +02:00
other => Err(ShellError::type_error("Path", other.tagged_type_name())),
2019-07-15 23:16:27 +02:00
}
}
2019-08-01 03:58:42 +02:00
fn check(value: &'value Tagged<Value>) -> Result<&'value Tagged<Value>, ShellError> {
2019-07-15 23:16:27 +02:00
match &value {
2019-08-01 03:58:42 +02:00
v @ Tagged {
2019-07-15 23:16:27 +02:00
item: Value::Primitive(Primitive::Path(_)),
..
} => Ok(v),
2019-08-01 03:58:42 +02:00
other => Err(ShellError::type_error("Path", other.tagged_type_name())),
2019-07-15 23:16:27 +02:00
}
}
}
2019-07-06 00:08:58 +02:00
#[derive(Debug, Deserialize, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, new)]
pub struct Integer;
impl Type for Integer {
2019-07-08 18:44:53 +02:00
type Extractor = i64;
fn name(&self) -> &'static str {
"Integer"
}
}
impl ExtractType for i64 {
2019-08-01 03:58:42 +02:00
fn extract(value: &Tagged<Value>) -> Result<i64, ShellError> {
2019-07-08 18:44:53 +02:00
match value {
2019-08-01 03:58:42 +02:00
&Tagged {
2019-07-08 18:44:53 +02:00
item: Value::Primitive(Primitive::Int(int)),
..
} => Ok(int),
2019-08-01 03:58:42 +02:00
other => Err(ShellError::type_error("Integer", other.tagged_type_name())),
2019-07-08 18:44:53 +02:00
}
}
2019-08-01 03:58:42 +02:00
fn check(value: &'value Tagged<Value>) -> Result<&'value Tagged<Value>, ShellError> {
2019-07-08 18:44:53 +02:00
match value {
2019-08-01 03:58:42 +02:00
v @ Tagged {
2019-07-08 18:44:53 +02:00
item: Value::Primitive(Primitive::Int(_)),
..
} => Ok(v),
2019-08-01 03:58:42 +02:00
other => Err(ShellError::type_error("Integer", other.tagged_type_name())),
2019-07-08 18:44:53 +02:00
}
}
}
#[derive(Debug, Deserialize, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, new)]
pub struct NuString;
impl Type for NuString {
type Extractor = String;
2019-07-06 00:08:58 +02:00
fn name(&self) -> &'static str {
"Integer"
}
}
2019-07-08 18:44:53 +02:00
impl ExtractType for String {
2019-08-01 03:58:42 +02:00
fn extract(value: &Tagged<Value>) -> Result<String, ShellError> {
2019-07-08 18:44:53 +02:00
match value {
2019-08-01 03:58:42 +02:00
Tagged {
2019-07-08 18:44:53 +02:00
item: Value::Primitive(Primitive::String(string)),
..
} => Ok(string.clone()),
2019-08-01 03:58:42 +02:00
other => Err(ShellError::type_error("String", other.tagged_type_name())),
2019-07-08 18:44:53 +02:00
}
}
2019-08-01 03:58:42 +02:00
fn check(value: &'value Tagged<Value>) -> Result<&'value Tagged<Value>, ShellError> {
2019-07-06 00:08:58 +02:00
match value {
2019-08-01 03:58:42 +02:00
v @ Tagged {
2019-07-09 06:31:26 +02:00
item: Value::Primitive(Primitive::String(_)),
2019-07-08 18:44:53 +02:00
..
} => Ok(v),
2019-08-01 03:58:42 +02:00
other => Err(ShellError::type_error("String", other.tagged_type_name())),
2019-07-06 00:08:58 +02:00
}
}
}
#[derive(Debug, Deserialize, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, new)]
pub struct Block;
impl Type for Block {
2019-07-08 18:44:53 +02:00
type Extractor = value::Block;
2019-07-06 00:08:58 +02:00
fn name(&self) -> &'static str {
"Block"
}
2019-07-09 06:31:26 +02:00
}
2019-07-06 00:08:58 +02:00
2019-07-09 06:31:26 +02:00
impl ExtractType for value::Block {
2019-08-01 03:58:42 +02:00
fn check(value: &'value Tagged<Value>) -> Result<&'value Tagged<Value>, ShellError> {
2019-07-06 00:08:58 +02:00
match value {
2019-08-01 03:58:42 +02:00
v @ Tagged {
2019-07-06 00:08:58 +02:00
item: Value::Block(_),
..
} => Ok(v),
2019-08-01 03:58:42 +02:00
other => Err(ShellError::type_error("Block", other.tagged_type_name())),
2019-07-06 00:08:58 +02:00
}
}
2019-08-01 03:58:42 +02:00
fn extract(value: &Tagged<Value>) -> Result<value::Block, ShellError> {
2019-07-08 18:44:53 +02:00
match value {
2019-08-01 03:58:42 +02:00
Tagged {
2019-07-08 18:44:53 +02:00
item: Value::Block(block),
..
} => Ok(block.clone()),
2019-08-01 03:58:42 +02:00
other => Err(ShellError::type_error("Block", other.tagged_type_name())),
2019-07-08 18:44:53 +02:00
}
}
2019-05-15 18:12:38 +02:00
}