2021-12-21 20:50:18 +00:00
use std ::fmt ::Display ;
2021-11-19 02:51:42 +00:00
use serde ::{ Deserialize , Serialize } ;
2021-09-02 01:29:43 +00:00
use crate ::Type ;
/// The syntactic shapes that values must match to be passed into a command. You can think of this as the type-checking that occurs when you call a function.
2021-11-19 02:51:42 +00:00
#[ derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize) ]
2021-09-02 01:29:43 +00:00
pub enum SyntaxShape {
/// A specific match to a word or symbol
Keyword ( Vec < u8 > , Box < SyntaxShape > ) ,
/// Any syntactic form is allowed
Any ,
/// Strings and string-like bare words are allowed
String ,
/// A dotted path to navigate the table
2021-09-06 22:02:24 +00:00
CellPath ,
2021-09-02 01:29:43 +00:00
/// A dotted path to navigate the table (including variable)
2021-09-06 22:02:24 +00:00
FullCellPath ,
2021-09-02 01:29:43 +00:00
/// Only a numeric (integer or decimal) value is allowed
Number ,
/// A range is allowed (eg, `1..3`)
Range ,
/// Only an integer value is allowed
Int ,
/// A filepath is allowed
2021-10-04 19:21:31 +00:00
Filepath ,
2021-09-02 01:29:43 +00:00
/// A glob pattern is allowed, eg `foo*`
GlobPattern ,
2021-09-26 18:39:19 +00:00
/// A module path pattern used for imports
ImportPattern ,
2021-09-02 01:29:43 +00:00
/// A block is allowed, eg `{start this thing}`
2021-09-13 07:54:13 +00:00
Block ( Option < Vec < SyntaxShape > > ) ,
2021-09-02 01:29:43 +00:00
/// A table is allowed, eg `[[first, second]; [1, 2]]`
Table ,
/// A table is allowed, eg `[first second]`
List ( Box < SyntaxShape > ) ,
/// A filesize value is allowed, eg `10kb`
Filesize ,
/// A duration value is allowed, eg `19day`
Duration ,
/// An operator
Operator ,
/// A math expression which expands shorthand forms on the lefthand side, eg `foo > 1`
/// The shorthand allows us to more easily reach columns inside of the row being passed in
RowCondition ,
/// A general math expression, eg `1 + 2`
MathExpression ,
/// A variable name
Variable ,
/// A variable with optional type, `x` or `x: int`
VarWithOptType ,
/// A signature for a definition, `[x:int, --foo]`
Signature ,
/// A general expression, eg `1 + 2` or `foo --bar`
Expression ,
2021-09-14 04:59:46 +00:00
2021-10-12 04:49:17 +00:00
/// A boolean value
Boolean ,
2021-09-14 04:59:46 +00:00
/// A custom shape with custom completion logic
Custom ( Box < SyntaxShape > , String ) ,
2021-09-02 01:29:43 +00:00
}
impl SyntaxShape {
pub fn to_type ( & self ) -> Type {
match self {
SyntaxShape ::Any = > Type ::Unknown ,
2021-09-13 07:54:13 +00:00
SyntaxShape ::Block ( _ ) = > Type ::Block ,
2021-09-06 22:02:24 +00:00
SyntaxShape ::CellPath = > Type ::Unknown ,
2021-09-14 04:59:46 +00:00
SyntaxShape ::Custom ( custom , _ ) = > custom . to_type ( ) ,
2021-09-02 01:29:43 +00:00
SyntaxShape ::Duration = > Type ::Duration ,
SyntaxShape ::Expression = > Type ::Unknown ,
2021-10-04 19:21:31 +00:00
SyntaxShape ::Filepath = > Type ::String ,
2021-09-02 01:29:43 +00:00
SyntaxShape ::Filesize = > Type ::Filesize ,
2021-09-06 22:02:24 +00:00
SyntaxShape ::FullCellPath = > Type ::Unknown ,
2021-09-02 01:29:43 +00:00
SyntaxShape ::GlobPattern = > Type ::String ,
2021-09-26 18:39:19 +00:00
SyntaxShape ::ImportPattern = > Type ::Unknown ,
2021-09-02 01:29:43 +00:00
SyntaxShape ::Int = > Type ::Int ,
SyntaxShape ::List ( x ) = > {
let contents = x . to_type ( ) ;
Type ::List ( Box ::new ( contents ) )
}
SyntaxShape ::Keyword ( _ , expr ) = > expr . to_type ( ) ,
SyntaxShape ::MathExpression = > Type ::Unknown ,
SyntaxShape ::Number = > Type ::Number ,
SyntaxShape ::Operator = > Type ::Unknown ,
SyntaxShape ::Range = > Type ::Unknown ,
SyntaxShape ::RowCondition = > Type ::Bool ,
2021-10-12 04:49:17 +00:00
SyntaxShape ::Boolean = > Type ::Bool ,
2021-09-02 01:29:43 +00:00
SyntaxShape ::Signature = > Type ::Unknown ,
SyntaxShape ::String = > Type ::String ,
2021-10-12 17:44:23 +00:00
SyntaxShape ::Table = > Type ::List ( Box ::new ( Type ::Unknown ) ) , // FIXME: Tables should have better types
2021-09-02 01:29:43 +00:00
SyntaxShape ::VarWithOptType = > Type ::Unknown ,
SyntaxShape ::Variable = > Type ::Unknown ,
}
}
}
2021-12-21 20:50:18 +00:00
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 ::Filepath = > write! ( f , " path " ) ,
SyntaxShape ::GlobPattern = > write! ( f , " glob " ) ,
SyntaxShape ::ImportPattern = > write! ( f , " import " ) ,
SyntaxShape ::Block ( _ ) = > write! ( f , " block " ) ,
SyntaxShape ::Table = > write! ( f , " table " ) ,
SyntaxShape ::List ( x ) = > write! ( f , " list<{}> " , x ) ,
SyntaxShape ::Filesize = > write! ( f , " filesize " ) ,
SyntaxShape ::Duration = > write! ( f , " duration " ) ,
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 ::Expression = > write! ( f , " expression " ) ,
SyntaxShape ::Boolean = > write! ( f , " bool " ) ,
SyntaxShape ::Custom ( x , _ ) = > write! ( f , " custom<{}> " , x ) ,
}
}
}