use std::fmt::Display;
use serde::{Deserialize, Serialize};
use crate::{DeclId, Type};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum SyntaxShape {
Any,
Binary,
Block,
Boolean,
CellPath,
Closure(Option<Vec<SyntaxShape>>),
Custom(Box<SyntaxShape>, DeclId),
DateTime,
Decimal,
Directory,
Duration,
Error,
Expression,
Filepath,
Filesize,
FullCellPath,
GlobPattern,
Int,
ImportPattern,
Keyword(Vec<u8>, Box<SyntaxShape>),
List(Box<SyntaxShape>),
MathExpression,
MatchBlock,
MatchPattern,
Nothing,
Number,
OneOf(Vec<SyntaxShape>),
Operator,
Range,
Record,
RowCondition,
Signature,
String,
Table,
Variable,
VarWithOptType,
}
impl SyntaxShape {
pub fn to_type(&self) -> Type {
match self {
SyntaxShape::Any => Type::Any,
SyntaxShape::Block => Type::Block,
SyntaxShape::Closure(_) => Type::Closure,
SyntaxShape::Binary => Type::Binary,
SyntaxShape::CellPath => Type::Any,
SyntaxShape::Custom(custom, _) => custom.to_type(),
SyntaxShape::DateTime => Type::Date,
SyntaxShape::Duration => Type::Duration,
SyntaxShape::Expression => Type::Any,
SyntaxShape::Filepath => Type::String,
SyntaxShape::Directory => Type::String,
SyntaxShape::Decimal => Type::Float,
SyntaxShape::Filesize => Type::Filesize,
SyntaxShape::FullCellPath => Type::Any,
SyntaxShape::GlobPattern => Type::String,
SyntaxShape::Error => Type::Error,
SyntaxShape::ImportPattern => Type::Any,
SyntaxShape::Int => Type::Int,
SyntaxShape::List(x) => {
let contents = x.to_type();
Type::List(Box::new(contents))
}
SyntaxShape::Keyword(_, expr) => expr.to_type(),
SyntaxShape::MatchBlock => Type::Any,
SyntaxShape::MatchPattern => Type::Any,
SyntaxShape::MathExpression => Type::Any,
SyntaxShape::Nothing => Type::Any,
SyntaxShape::Number => Type::Number,
SyntaxShape::OneOf(_) => Type::Any,
SyntaxShape::Operator => Type::Any,
SyntaxShape::Range => Type::Any,
SyntaxShape::Record => Type::Record(vec![]), SyntaxShape::RowCondition => Type::Bool,
SyntaxShape::Boolean => Type::Bool,
SyntaxShape::Signature => Type::Signature,
SyntaxShape::String => Type::String,
SyntaxShape::Table => Type::Table(vec![]), SyntaxShape::VarWithOptType => Type::Any,
SyntaxShape::Variable => Type::Any,
}
}
}
impl Display for SyntaxShape {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SyntaxShape::Keyword(kw, shape) => {
write!(f, "\"{}\" {}", String::from_utf8_lossy(kw), shape)
}
SyntaxShape::Any => write!(f, "any"),
SyntaxShape::String => write!(f, "string"),
SyntaxShape::CellPath => write!(f, "cellpath"),
SyntaxShape::FullCellPath => write!(f, "cellpath"),
SyntaxShape::Number => write!(f, "number"),
SyntaxShape::Range => write!(f, "range"),
SyntaxShape::Int => write!(f, "int"),
SyntaxShape::Decimal => write!(f, "decimal"),
SyntaxShape::Filepath => write!(f, "path"),
SyntaxShape::Directory => write!(f, "directory"),
SyntaxShape::GlobPattern => write!(f, "glob"),
SyntaxShape::ImportPattern => write!(f, "import"),
SyntaxShape::Block => write!(f, "block"),
SyntaxShape::Closure(args) => {
if let Some(args) = args {
let arg_vec: Vec<_> = args.iter().map(|x| x.to_string()).collect();
let arg_string = arg_vec.join(", ");
write!(f, "closure({arg_string})")
} else {
write!(f, "closure()")
}
}
SyntaxShape::Binary => write!(f, "binary"),
SyntaxShape::Table => write!(f, "table"),
SyntaxShape::List(x) => write!(f, "list<{x}>"),
SyntaxShape::Record => write!(f, "record"),
SyntaxShape::Filesize => write!(f, "filesize"),
SyntaxShape::Duration => write!(f, "duration"),
SyntaxShape::DateTime => write!(f, "datetime"),
SyntaxShape::Operator => write!(f, "operator"),
SyntaxShape::RowCondition => write!(f, "condition"),
SyntaxShape::MathExpression => write!(f, "variable"),
SyntaxShape::Variable => write!(f, "var"),
SyntaxShape::VarWithOptType => write!(f, "vardecl"),
SyntaxShape::Signature => write!(f, "signature"),
SyntaxShape::MatchPattern => write!(f, "matchpattern"),
SyntaxShape::MatchBlock => write!(f, "matchblock"),
SyntaxShape::Expression => write!(f, "expression"),
SyntaxShape::Boolean => write!(f, "bool"),
SyntaxShape::Error => write!(f, "error"),
SyntaxShape::Custom(x, _) => write!(f, "custom<{x}>"),
SyntaxShape::OneOf(list) => {
let arg_vec: Vec<_> = list.iter().map(|x| x.to_string()).collect();
let arg_string = arg_vec.join(", ");
write!(f, "one_of({arg_string})")
}
SyntaxShape::Nothing => write!(f, "nothing"),
}
}
}