This commit is contained in:
Yehuda Katz 2019-07-05 15:08:58 -07:00
parent 34033afce4
commit 71adfb4cdc
6 changed files with 88 additions and 11 deletions

View File

@ -262,7 +262,9 @@ macro_rules! command {
Extract {
$($extract:tt)* {
use std::convert::TryInto;
$args.expect_nth($($positional_count)*)?.try_into()?
let value = $args.expect_nth($($positional_count)*)?;
let value = $param_kind.check(value)?;
value.extract()
}
}
);

View File

@ -1,7 +1,6 @@
use crate::errors::ShellError;
use crate::object::{Primitive, Switch, Value};
use crate::parser::parse::span::Span;
use crate::parser::registry::NamedType;
use crate::prelude::*;
use mime::Mime;
use std::path::{Path, PathBuf};

View File

@ -1,5 +1,5 @@
use crate::errors::ShellError;
use crate::object::Block;
use crate::object::types::*;
use crate::prelude::*;
use futures::future::ready;
use log::trace;

View File

@ -149,11 +149,6 @@ impl Deserialize<'de> for Block {
D: Deserializer<'de>,
{
unimplemented!("deserialize block")
// let s = "\"unimplemented deserialize block\"";
// Ok(Block::new(
// TokenTreeBuilder::spanned_string((1, s.len() - 1), (0, s.len())),
// Text::from(s),
// ))
}
}

View File

@ -1,7 +1,86 @@
use crate::object::base as value;
use crate::parser::hir;
use crate::prelude::*;
use derive_new::new;
use serde_derive::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, new)]
pub enum Type {
Any,
pub trait Type: std::fmt::Debug + Send {
fn name(&self) -> &'static str;
fn check(&self, value: Spanned<Value>) -> Result<Spanned<Value>, ShellError>;
fn coerce(&self) -> Option<hir::ExpressionKindHint> {
None
}
}
pub trait ExtractType<T>: Type {
fn extract(value: Value) -> T;
}
#[derive(Debug, Deserialize, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, new)]
pub struct Any;
impl Type for Any {
fn name(&self) -> &'static str {
"Any"
}
fn check(&self, value: Spanned<Value>) -> Result<Spanned<Value>, ShellError> {
Ok(value)
}
}
#[derive(Debug, Deserialize, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, new)]
pub struct Integer;
impl Type for Integer {
fn name(&self) -> &'static str {
"Integer"
}
fn check(&self, value: Spanned<Value>) -> Result<Spanned<Value>, ShellError> {
match value {
v @ Spanned {
item: Value::Primitive(Primitive::Int(_)),
..
} => Ok(v),
other => Err(ShellError::type_error("Integer", other.spanned_type_name())),
}
}
}
impl ExtractType<i64> for Integer {
fn extract(value: Value) -> i64 {
match value {
Value::Primitive(Primitive::Int(int)) => int,
_ => unreachable!("invariant: must check before extract"),
}
}
}
#[derive(Debug, Deserialize, Clone, Eq, PartialEq, Hash, Ord, PartialOrd, new)]
pub struct Block;
impl Type for Block {
fn name(&self) -> &'static str {
"Block"
}
fn check(&self, value: Spanned<Value>) -> Result<Spanned<Value>, ShellError> {
match value {
v @ Spanned {
item: Value::Block(_),
..
} => Ok(v),
other => Err(ShellError::type_error("Block", other.spanned_type_name())),
}
}
}
impl ExtractType<value::Block> for Block {
fn extract(value: Value) -> value::Block {
match value {
Value::Block(block) => block,
_ => unreachable!("invariant: must check before extract"),
}
}
}

View File

@ -40,7 +40,9 @@ crate use crate::context::Context;
crate use crate::env::host::handle_unexpected;
crate use crate::env::{Environment, Host};
crate use crate::errors::ShellError;
crate use crate::object::types::{ExtractType, Type};
crate use crate::object::{Primitive, Value};
crate use crate::parser::{Span, Spanned};
crate use crate::stream::{InputStream, OutputStream};
crate use crate::Text;
crate use futures::stream::BoxStream;