Revert "Remove structure from map types"
This reverts commit 5e685d6641
.
This commit is contained in:
parent
5e685d6641
commit
390d1aa504
@ -6,7 +6,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
use crate::{
|
use crate::{
|
||||||
built_in_functions::{fs::fs_functions, json::json_functions, str::string_functions, Callable},
|
built_in_functions::{fs::fs_functions, json::json_functions, str::string_functions, Callable},
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
AbstractTree, BuiltInFunction, Context, Format, Function, List, Map, SyntaxNode, Type, Value,
|
AbstractTree, BuiltInFunction, Context, Format, Function, List, Map, Structure, SyntaxNode,
|
||||||
|
Type, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
static ARGS: OnceLock<Value> = OnceLock::new();
|
static ARGS: OnceLock<Value> = OnceLock::new();
|
||||||
@ -86,12 +87,14 @@ impl BuiltInValue {
|
|||||||
match self {
|
match self {
|
||||||
BuiltInValue::Args => Type::list(Type::String),
|
BuiltInValue::Args => Type::list(Type::String),
|
||||||
BuiltInValue::AssertEqual => BuiltInFunction::AssertEqual.r#type(),
|
BuiltInValue::AssertEqual => BuiltInFunction::AssertEqual.r#type(),
|
||||||
BuiltInValue::Fs => Type::Map,
|
BuiltInValue::Fs => Type::Map(None),
|
||||||
BuiltInValue::Json => Type::Map,
|
BuiltInValue::Json => Type::Map(Some(
|
||||||
|
Structure::from_map(self.get().as_map().unwrap()).unwrap(),
|
||||||
|
)),
|
||||||
BuiltInValue::Length => BuiltInFunction::Length.r#type(),
|
BuiltInValue::Length => BuiltInFunction::Length.r#type(),
|
||||||
BuiltInValue::Output => BuiltInFunction::Output.r#type(),
|
BuiltInValue::Output => BuiltInFunction::Output.r#type(),
|
||||||
BuiltInValue::Random => Type::Map,
|
BuiltInValue::Random => Type::Map(None),
|
||||||
BuiltInValue::Str => Type::Map,
|
BuiltInValue::Str => Type::Map(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,17 @@ impl AbstractTree for Index {
|
|||||||
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError> {
|
||||||
match self.collection.expected_type(context)? {
|
match self.collection.expected_type(context)? {
|
||||||
Type::List(item_type) => Ok(*item_type.clone()),
|
Type::List(item_type) => Ok(*item_type.clone()),
|
||||||
Type::Map => Ok(Type::Any),
|
Type::Map(structure) => {
|
||||||
|
if let Some(structure) = structure {
|
||||||
|
if let IndexExpression::Identifier(identifier) = &self.index {
|
||||||
|
if let Some((_, r#type)) = structure.inner().get(identifier.inner()) {
|
||||||
|
return Ok(r#type.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Type::Any)
|
||||||
|
}
|
||||||
Type::None => Ok(Type::None),
|
Type::None => Ok(Type::None),
|
||||||
r#type => Ok(r#type),
|
r#type => Ok(r#type),
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::{RuntimeError, SyntaxError, ValidationError},
|
error::{RuntimeError, SyntaxError, ValidationError},
|
||||||
AbstractTree, Context, Format, Identifier, SyntaxNode, Value,
|
AbstractTree, Context, Format, Identifier, Structure, SyntaxNode, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||||
@ -20,7 +20,7 @@ pub enum Type {
|
|||||||
},
|
},
|
||||||
Integer,
|
Integer,
|
||||||
List(Box<Type>),
|
List(Box<Type>),
|
||||||
Map,
|
Map(Option<Structure>),
|
||||||
None,
|
None,
|
||||||
Number,
|
Number,
|
||||||
String,
|
String,
|
||||||
@ -58,13 +58,13 @@ impl Type {
|
|||||||
| (Type::Collection, Type::Collection)
|
| (Type::Collection, Type::Collection)
|
||||||
| (Type::Collection, Type::List(_))
|
| (Type::Collection, Type::List(_))
|
||||||
| (Type::List(_), Type::Collection)
|
| (Type::List(_), Type::Collection)
|
||||||
| (Type::Collection, Type::Map)
|
| (Type::Collection, Type::Map(_))
|
||||||
| (Type::Map, Type::Collection)
|
| (Type::Map(_), Type::Collection)
|
||||||
| (Type::Collection, Type::String)
|
| (Type::Collection, Type::String)
|
||||||
| (Type::String, Type::Collection)
|
| (Type::String, Type::Collection)
|
||||||
| (Type::Float, Type::Float)
|
| (Type::Float, Type::Float)
|
||||||
| (Type::Integer, Type::Integer)
|
| (Type::Integer, Type::Integer)
|
||||||
| (Type::Map, Type::Map)
|
| (Type::Map(_), Type::Map(_))
|
||||||
| (Type::Number, Type::Number)
|
| (Type::Number, Type::Number)
|
||||||
| (Type::Number, Type::Integer)
|
| (Type::Number, Type::Integer)
|
||||||
| (Type::Number, Type::Float)
|
| (Type::Number, Type::Float)
|
||||||
@ -121,7 +121,7 @@ impl Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_map(&self) -> bool {
|
pub fn is_map(&self) -> bool {
|
||||||
matches!(self, Type::Map)
|
matches!(self, Type::Map(_))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ impl AbstractTree for Type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"int" => Type::Integer,
|
"int" => Type::Integer,
|
||||||
"map" => Type::Map,
|
"map" => Type::Map(None),
|
||||||
"num" => Type::Number,
|
"num" => Type::Number,
|
||||||
"none" => Type::None,
|
"none" => Type::None,
|
||||||
"str" => Type::String,
|
"str" => Type::String,
|
||||||
@ -241,9 +241,13 @@ impl Format for Type {
|
|||||||
item_type.format(output, indent_level);
|
item_type.format(output, indent_level);
|
||||||
output.push(']');
|
output.push(']');
|
||||||
}
|
}
|
||||||
Type::Map => {
|
Type::Map(structure_option) => {
|
||||||
|
if let Some(structure) = structure_option {
|
||||||
|
output.push_str(&structure.to_string());
|
||||||
|
} else {
|
||||||
output.push_str("map");
|
output.push_str("map");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Type::None => output.push_str("none"),
|
Type::None => output.push_str("none"),
|
||||||
Type::Number => output.push_str("num"),
|
Type::Number => output.push_str("num"),
|
||||||
Type::String => output.push_str("str"),
|
Type::String => output.push_str("str"),
|
||||||
@ -284,7 +288,7 @@ impl Display for Type {
|
|||||||
}
|
}
|
||||||
Type::Integer => write!(f, "int"),
|
Type::Integer => write!(f, "int"),
|
||||||
Type::List(item_type) => write!(f, "[{item_type}]"),
|
Type::List(item_type) => write!(f, "[{item_type}]"),
|
||||||
Type::Map => write!(f, "map"),
|
Type::Map(_) => write!(f, "map"),
|
||||||
Type::Number => write!(f, "num"),
|
Type::Number => write!(f, "num"),
|
||||||
Type::None => write!(f, "none"),
|
Type::None => write!(f, "none"),
|
||||||
Type::String => write!(f, "str"),
|
Type::String => write!(f, "str"),
|
||||||
|
@ -217,9 +217,17 @@ impl AbstractTree for ValueNode {
|
|||||||
Type::None
|
Type::None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ValueNode::Map(_, _) => Type::Map,
|
ValueNode::Map(_, _) => Type::Map(None),
|
||||||
ValueNode::BuiltInValue(built_in_value) => built_in_value.expected_type(context)?,
|
ValueNode::BuiltInValue(built_in_value) => built_in_value.expected_type(context)?,
|
||||||
ValueNode::Structure(_) => Type::Map,
|
ValueNode::Structure(node_map) => {
|
||||||
|
let mut value_map = BTreeMap::new();
|
||||||
|
|
||||||
|
for (key, (_statement_option, r#type)) in node_map {
|
||||||
|
value_map.insert(key.to_string(), (None, r#type.clone()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Type::Map(Some(Structure::new(value_map)))
|
||||||
|
}
|
||||||
ValueNode::Range(_) => Type::Range,
|
ValueNode::Range(_) => Type::Range,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//! Types that represent runtime values.
|
//! Types that represent runtime values.
|
||||||
use crate::{error::RuntimeError, Type};
|
use crate::{error::RuntimeError, Identifier, Type, TypeSpecification};
|
||||||
|
|
||||||
use serde::{
|
use serde::{
|
||||||
de::{MapAccess, SeqAccess, Visitor},
|
de::{MapAccess, SeqAccess, Visitor},
|
||||||
@ -80,7 +80,18 @@ impl Value {
|
|||||||
Type::List(Box::new(Type::Any))
|
Type::List(Box::new(Type::Any))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::Map(_) => Type::Map,
|
Value::Map(map) => {
|
||||||
|
let mut identifier_types = Vec::new();
|
||||||
|
|
||||||
|
for (key, value) in map.inner().unwrap().iter() {
|
||||||
|
identifier_types.push((
|
||||||
|
Identifier::new(key.clone()),
|
||||||
|
TypeSpecification::new(value.r#type()),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Type::Map(None)
|
||||||
|
}
|
||||||
Value::Function(function) => function.r#type().clone(),
|
Value::Function(function) => function.r#type().clone(),
|
||||||
Value::String(_) => Type::String,
|
Value::String(_) => Type::String,
|
||||||
Value::Float(_) => Type::Float,
|
Value::Float(_) => Type::Float,
|
||||||
|
@ -39,7 +39,7 @@ fn conversion_runtime_error() {
|
|||||||
interpret(&format!("json:parse('{JSON}') as [map]")),
|
interpret(&format!("json:parse('{JSON}') as [map]")),
|
||||||
Err(Error::Runtime(RuntimeError::ConversionImpossible {
|
Err(Error::Runtime(RuntimeError::ConversionImpossible {
|
||||||
value: json_value,
|
value: json_value,
|
||||||
target_type: Type::List(Box::new(Type::Map))
|
target_type: Type::List(Box::new(Type::Map(None)))
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user