refactor(ast): rename value types to Number/Decimal/Text/Boolean

Renamed AST value types for v0.3 naming convention:
- Value::Int -> Value::Number
- Value::Float -> Value::Decimal
- Value::String -> Value::Text
- Value::Bool -> Value::Boolean
- Expr::IntLit -> Expr::NumberLit
- Expr::FloatLit -> Expr::DecimalLit
- Expr::StringLit -> Expr::TextLit
- Expr::BoolLit -> Expr::BooleanLit

Updated all references across parser, resolver, validator, LSP,
query engine, tests, and editor.
This commit is contained in:
2026-02-14 14:03:21 +00:00
parent 8c3c380cfd
commit 8e4bdd3942
21 changed files with 188 additions and 188 deletions

View File

@@ -216,7 +216,7 @@ fn test_unknown_life_arc_state_error() {
on_enter: None, on_enter: None,
transitions: vec![Transition { transitions: vec![Transition {
to: "adult".to_string(), // 'adult' exists to: "adult".to_string(), // 'adult' exists
condition: Expr::BoolLit(true), condition: Expr::BooleanLit(true),
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
span: Span::new(0, 50), span: Span::new(0, 50),
@@ -226,7 +226,7 @@ fn test_unknown_life_arc_state_error() {
on_enter: None, on_enter: None,
transitions: vec![Transition { transitions: vec![Transition {
to: "senior".to_string(), // 'senior' doesn't exist! to: "senior".to_string(), // 'senior' doesn't exist!
condition: Expr::BoolLit(true), condition: Expr::BooleanLit(true),
span: Span::new(50, 60), span: Span::new(50, 60),
}], }],
span: Span::new(50, 100), span: Span::new(50, 100),
@@ -252,7 +252,7 @@ fn test_unknown_life_arc_state_error() {
fn test_trait_out_of_range_error_bond() { fn test_trait_out_of_range_error_bond() {
let fields = vec![Field { let fields = vec![Field {
name: "bond".to_string(), name: "bond".to_string(),
value: Value::Float(1.5), // Out of range! value: Value::Decimal(1.5), // Out of range!
span: Span::new(0, 10), span: Span::new(0, 10),
}]; }];
@@ -276,7 +276,7 @@ fn test_trait_out_of_range_error_bond() {
fn test_trait_out_of_range_error_age() { fn test_trait_out_of_range_error_age() {
let fields = vec![Field { let fields = vec![Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Int(200), // Out of range! value: Value::Number(200), // Out of range!
span: Span::new(0, 10), span: Span::new(0, 10),
}]; }];
@@ -297,7 +297,7 @@ fn test_trait_out_of_range_error_age() {
fn test_trait_out_of_range_negative() { fn test_trait_out_of_range_negative() {
let fields = vec![Field { let fields = vec![Field {
name: "trust".to_string(), name: "trust".to_string(),
value: Value::Float(-0.2), // Negative! value: Value::Decimal(-0.2), // Negative!
span: Span::new(0, 10), span: Span::new(0, 10),
}]; }];
@@ -411,7 +411,7 @@ fn test_relationship_bond_out_of_range() {
participants: vec![], participants: vec![],
fields: vec![Field { fields: vec![Field {
name: "bond".to_string(), name: "bond".to_string(),
value: Value::Float(2.5), // Way out of range! value: Value::Decimal(2.5), // Way out of range!
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
span: Span::new(0, 50), span: Span::new(0, 50),
@@ -438,12 +438,12 @@ fn test_duplicate_field_in_convert() {
fields: vec![ fields: vec![
Field { Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Int(34), value: Value::Number(34),
span: Span::new(0, 10), span: Span::new(0, 10),
}, },
Field { Field {
name: "age".to_string(), // Duplicate! name: "age".to_string(), // Duplicate!
value: Value::Int(35), value: Value::Number(35),
span: Span::new(10, 20), span: Span::new(10, 20),
}, },
], ],

View File

@@ -2389,10 +2389,10 @@ fn get_default_value_for_type(field_type: &crate::syntax::ast::Value) -> String
} }
}, },
| Value::List(_) => String::from("[]"), | Value::List(_) => String::from("[]"),
| Value::String(_) => String::from("\"\""), | Value::Text(_) => String::from("\"\""),
| Value::Int(_) => String::from("0"), | Value::Number(_) => String::from("0"),
| Value::Float(_) => String::from("0.0"), | Value::Decimal(_) => String::from("0.0"),
| Value::Bool(_) => String::from("false"), | Value::Boolean(_) => String::from("false"),
| Value::Object(_) => String::from("{}"), | Value::Object(_) => String::from("{}"),
| Value::Range(_, _) => String::from("0..10"), | Value::Range(_, _) => String::from("0..10"),
| Value::Time(_) => String::from("00:00"), | Value::Time(_) => String::from("00:00"),
@@ -2408,10 +2408,10 @@ fn format_value(value: &crate::syntax::ast::Value) -> String {
use crate::syntax::ast::Value; use crate::syntax::ast::Value;
match value { match value {
| Value::String(s) => format!("\"{}\"", s), | Value::Text(s) => format!("\"{}\"", s),
| Value::Int(n) => n.to_string(), | Value::Number(n) => n.to_string(),
| Value::Float(f) => f.to_string(), | Value::Decimal(f) => f.to_string(),
| Value::Bool(b) => b.to_string(), | Value::Boolean(b) => b.to_string(),
| Value::Identifier(path) => path.join("."), | Value::Identifier(path) => path.join("."),
| Value::List(items) => { | Value::List(items) => {
let formatted: Vec<String> = items.iter().map(format_value).collect(); let formatted: Vec<String> = items.iter().map(format_value).collect();
@@ -2443,10 +2443,10 @@ fn infer_type_from_value(value: &crate::syntax::ast::Value) -> String {
use crate::syntax::ast::Value; use crate::syntax::ast::Value;
match value { match value {
| Value::String(_) => String::from("String"), | Value::Text(_) => String::from("Text"),
| Value::Int(_) => String::from("Int"), | Value::Number(_) => String::from("Number"),
| Value::Float(_) => String::from("Float"), | Value::Decimal(_) => String::from("Decimal"),
| Value::Bool(_) => String::from("Bool"), | Value::Boolean(_) => String::from("Boolean"),
| Value::Identifier(path) => path.join("."), // Reference type | Value::Identifier(path) => path.join("."), // Reference type
| Value::List(items) => { | Value::List(items) => {
if items.is_empty() { if items.is_empty() {

View File

@@ -209,10 +209,10 @@ fn is_typing_declaration_name(text: &str, offset: usize) -> bool {
fn format_value_type(value: &Value) -> String { fn format_value_type(value: &Value) -> String {
match value { match value {
| Value::Identifier(path) => path.join("."), | Value::Identifier(path) => path.join("."),
| Value::String(_) => "String".to_string(), | Value::Text(_) => "Text".to_string(),
| Value::Int(_) => "Int".to_string(), | Value::Number(_) => "Number".to_string(),
| Value::Float(_) => "Float".to_string(), | Value::Decimal(_) => "Decimal".to_string(),
| Value::Bool(_) => "Bool".to_string(), | Value::Boolean(_) => "Boolean".to_string(),
| Value::List(items) => { | Value::List(items) => {
if items.is_empty() { if items.is_empty() {
"List".to_string() "List".to_string()

View File

@@ -526,10 +526,10 @@ fn format_behavior_node_preview(node: &crate::syntax::ast::BehaviorNode, depth:
fn format_value_as_type(value: &Value) -> String { fn format_value_as_type(value: &Value) -> String {
match value { match value {
| Value::Identifier(path) => path.join("."), | Value::Identifier(path) => path.join("."),
| Value::String(_) => "String".to_string(), | Value::Text(_) => "Text".to_string(),
| Value::Int(_) => "Int".to_string(), | Value::Number(_) => "Number".to_string(),
| Value::Float(_) => "Float".to_string(), | Value::Decimal(_) => "Decimal".to_string(),
| Value::Bool(_) => "Bool".to_string(), | Value::Boolean(_) => "Boolean".to_string(),
| Value::List(items) => { | Value::List(items) => {
if items.is_empty() { if items.is_empty() {
"List".to_string() "List".to_string()
@@ -557,10 +557,10 @@ fn format_value_as_type(value: &Value) -> String {
fn format_value_preview(value: &Value) -> String { fn format_value_preview(value: &Value) -> String {
match value { match value {
| Value::Identifier(path) => format!("`{}`", path.join(".")), | Value::Identifier(path) => format!("`{}`", path.join(".")),
| Value::String(s) => format!("\"{}\"", truncate(s, 50)), | Value::Text(s) => format!("\"{}\"", truncate(s, 50)),
| Value::Int(n) => n.to_string(), | Value::Number(n) => n.to_string(),
| Value::Float(f) => f.to_string(), | Value::Decimal(f) => f.to_string(),
| Value::Bool(b) => b.to_string(), | Value::Boolean(b) => b.to_string(),
| Value::List(items) => { | Value::List(items) => {
if items.is_empty() { if items.is_empty() {
"[]".to_string() "[]".to_string()

View File

@@ -145,7 +145,7 @@ fn add_type_hint(
// Only add hints for non-obvious types // Only add hints for non-obvious types
// Skip if the type is clear from the literal (e.g., "string", 123, true) // Skip if the type is clear from the literal (e.g., "string", 123, true)
let should_hint = match &field.value { let should_hint = match &field.value {
| Value::String(_) | Value::Int(_) | Value::Float(_) | Value::Bool(_) => false, | Value::Text(_) | Value::Number(_) | Value::Decimal(_) | Value::Boolean(_) => false,
| Value::Identifier(_) => true, // Show type for identifier references | Value::Identifier(_) => true, // Show type for identifier references
| Value::List(_) => true, // Show list element type | Value::List(_) => true, // Show list element type
| Value::Object(_) => false, // Object structure is visible | Value::Object(_) => false, // Object structure is visible
@@ -183,10 +183,10 @@ fn add_type_hint(
fn infer_value_type(value: &Value) -> String { fn infer_value_type(value: &Value) -> String {
match value { match value {
| Value::Identifier(path) => path.join("."), | Value::Identifier(path) => path.join("."),
| Value::String(_) => "String".to_string(), | Value::Text(_) => "Text".to_string(),
| Value::Int(_) => "Int".to_string(), | Value::Number(_) => "Number".to_string(),
| Value::Float(_) => "Float".to_string(), | Value::Decimal(_) => "Decimal".to_string(),
| Value::Bool(_) => "Bool".to_string(), | Value::Boolean(_) => "Boolean".to_string(),
| Value::List(items) => { | Value::List(items) => {
if items.is_empty() { if items.is_empty() {
"[]".to_string() "[]".to_string()

View File

@@ -411,14 +411,14 @@ fn highlight_field(builder: &mut SemanticTokensBuilder, field: &Field) {
/// Helper to highlight a value /// Helper to highlight a value
fn highlight_value(builder: &mut SemanticTokensBuilder, value: &Value) { fn highlight_value(builder: &mut SemanticTokensBuilder, value: &Value) {
match value { match value {
| Value::String(_s) => { | Value::Text(_s) => {
// String literals are already highlighted by the grammar // Text literals are already highlighted by the grammar
// but we could add semantic highlighting here if needed // but we could add semantic highlighting here if needed
}, },
| Value::Int(_) | Value::Float(_) => { | Value::Number(_) | Value::Decimal(_) => {
// Number literals are already highlighted by the grammar // Number literals are already highlighted by the grammar
}, },
| Value::Bool(_) => { | Value::Boolean(_) => {
// Boolean literals are already highlighted by the grammar // Boolean literals are already highlighted by the grammar
}, },
| Value::Identifier(_path) => { | Value::Identifier(_path) => {

View File

@@ -50,7 +50,7 @@ where
max: i64, max: i64,
) -> Box<dyn Iterator<Item = &'a ResolvedCharacter> + 'a> { ) -> Box<dyn Iterator<Item = &'a ResolvedCharacter> + 'a> {
Box::new(self.filter(move |c| { Box::new(self.filter(move |c| {
if let Some(Value::Int(age)) = c.fields.get("age") { if let Some(Value::Number(age)) = c.fields.get("age") {
*age >= min && *age <= max *age >= min && *age <= max
} else { } else {
false false
@@ -65,7 +65,7 @@ where
max: f64, max: f64,
) -> Box<dyn Iterator<Item = &'a ResolvedCharacter> + 'a> { ) -> Box<dyn Iterator<Item = &'a ResolvedCharacter> + 'a> {
Box::new(self.filter(move |c| { Box::new(self.filter(move |c| {
if let Some(Value::Float(value)) = c.fields.get(trait_name) { if let Some(Value::Decimal(value)) = c.fields.get(trait_name) {
*value >= min && *value <= max *value >= min && *value <= max
} else { } else {
false false
@@ -121,7 +121,7 @@ where
max: f64, max: f64,
) -> Box<dyn Iterator<Item = &'a ResolvedRelationship> + 'a> { ) -> Box<dyn Iterator<Item = &'a ResolvedRelationship> + 'a> {
Box::new(self.filter(move |r| { Box::new(self.filter(move |r| {
if let Some(Value::Float(bond)) = r.fields.get("bond") { if let Some(Value::Decimal(bond)) = r.fields.get("bond") {
*bond >= min && *bond <= max *bond >= min && *bond <= max
} else { } else {
false false
@@ -178,8 +178,8 @@ mod tests {
fn make_character(name: &str, age: i64, trust: f64) -> ResolvedCharacter { fn make_character(name: &str, age: i64, trust: f64) -> ResolvedCharacter {
let mut fields = HashMap::new(); let mut fields = HashMap::new();
fields.insert("age".to_string(), Value::Int(age)); fields.insert("age".to_string(), Value::Number(age));
fields.insert("trust".to_string(), Value::Float(trust)); fields.insert("trust".to_string(), Value::Decimal(trust));
ResolvedCharacter { ResolvedCharacter {
name: name.to_string(), name: name.to_string(),
@@ -248,7 +248,7 @@ mod tests {
let mut char1 = make_character("Alice", 25, 0.8); let mut char1 = make_character("Alice", 25, 0.8);
char1 char1
.fields .fields
.insert("job".to_string(), Value::String("baker".to_string())); .insert("job".to_string(), Value::Text("baker".to_string()));
let char2 = make_character("Bob", 35, 0.6); let char2 = make_character("Bob", 35, 0.6);
@@ -263,10 +263,10 @@ mod tests {
#[test] #[test]
fn test_relationship_with_bond_range() { fn test_relationship_with_bond_range() {
let mut fields1 = HashMap::new(); let mut fields1 = HashMap::new();
fields1.insert("bond".to_string(), Value::Float(0.9)); fields1.insert("bond".to_string(), Value::Decimal(0.9));
let mut fields2 = HashMap::new(); let mut fields2 = HashMap::new();
fields2.insert("bond".to_string(), Value::Float(0.5)); fields2.insert("bond".to_string(), Value::Decimal(0.5));
let relationships = [ let relationships = [
ResolvedRelationship { ResolvedRelationship {

View File

@@ -384,12 +384,12 @@ mod tests {
fields: vec![ fields: vec![
Field { Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Int(34), value: Value::Number(34),
span: Span::new(0, 10), span: Span::new(0, 10),
}, },
Field { Field {
name: "health".to_string(), name: "health".to_string(),
value: Value::Float(0.8), value: Value::Decimal(0.8),
span: Span::new(10, 20), span: Span::new(10, 20),
}, },
], ],
@@ -403,8 +403,8 @@ mod tests {
assert_eq!(resolved.name, "Martha"); assert_eq!(resolved.name, "Martha");
assert_eq!(resolved.fields.len(), 2); assert_eq!(resolved.fields.len(), 2);
assert_eq!(resolved.fields.get("age"), Some(&Value::Int(34))); assert_eq!(resolved.fields.get("age"), Some(&Value::Number(34)));
assert_eq!(resolved.fields.get("health"), Some(&Value::Float(0.8))); assert_eq!(resolved.fields.get("health"), Some(&Value::Decimal(0.8)));
assert_eq!(resolved.prose_blocks.len(), 0); assert_eq!(resolved.prose_blocks.len(), 0);
} }
@@ -422,7 +422,7 @@ mod tests {
fields: vec![ fields: vec![
Field { Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Int(34), value: Value::Number(34),
span: Span::new(0, 10), span: Span::new(0, 10),
}, },
Field { Field {
@@ -441,7 +441,7 @@ mod tests {
assert_eq!(resolved.name, "Martha"); assert_eq!(resolved.name, "Martha");
assert_eq!(resolved.fields.len(), 1); assert_eq!(resolved.fields.len(), 1);
assert_eq!(resolved.fields.get("age"), Some(&Value::Int(34))); assert_eq!(resolved.fields.get("age"), Some(&Value::Number(34)));
assert_eq!(resolved.prose_blocks.len(), 1); assert_eq!(resolved.prose_blocks.len(), 1);
assert_eq!(resolved.prose_blocks.get("backstory"), Some(&prose_block)); assert_eq!(resolved.prose_blocks.get("backstory"), Some(&prose_block));
} }
@@ -454,12 +454,12 @@ mod tests {
fields: vec![ fields: vec![
Field { Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Int(34), value: Value::Number(34),
span: Span::new(0, 10), span: Span::new(0, 10),
}, },
Field { Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Int(35), value: Value::Number(35),
span: Span::new(10, 20), span: Span::new(10, 20),
}, },
], ],
@@ -481,7 +481,7 @@ mod tests {
species: None, species: None,
fields: vec![Field { fields: vec![Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Int(34), value: Value::Number(34),
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
template: None, template: None,
@@ -550,7 +550,7 @@ mod tests {
let fields = vec![ let fields = vec![
Field { Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Int(30), value: Value::Number(30),
span: Span::new(0, 10), span: Span::new(0, 10),
}, },
Field { Field {
@@ -560,7 +560,7 @@ mod tests {
}, },
Field { Field {
name: "active".to_string(), name: "active".to_string(),
value: Value::Bool(true), value: Value::Boolean(true),
span: Span::new(30, 40), span: Span::new(30, 40),
}, },
]; ];
@@ -568,8 +568,8 @@ mod tests {
let (field_map, prose_map) = extract_fields_and_prose(&fields).unwrap(); let (field_map, prose_map) = extract_fields_and_prose(&fields).unwrap();
assert_eq!(field_map.len(), 2); assert_eq!(field_map.len(), 2);
assert_eq!(field_map.get("age"), Some(&Value::Int(30))); assert_eq!(field_map.get("age"), Some(&Value::Number(30)));
assert_eq!(field_map.get("active"), Some(&Value::Bool(true))); assert_eq!(field_map.get("active"), Some(&Value::Boolean(true)));
assert_eq!(prose_map.len(), 1); assert_eq!(prose_map.len(), 1);
assert_eq!(prose_map.get("description"), Some(&prose_block)); assert_eq!(prose_map.get("description"), Some(&prose_block));
@@ -585,7 +585,7 @@ mod tests {
name: "Person".to_string(), name: "Person".to_string(),
fields: vec![Field { fields: vec![Field {
name: "type".to_string(), // Changed from "species" name: "type".to_string(), // Changed from "species"
value: Value::String("human".to_string()), value: Value::Text("human".to_string()),
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
strict: false, strict: false,
@@ -600,7 +600,7 @@ mod tests {
species: None, species: None,
fields: vec![Field { fields: vec![Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Int(34), value: Value::Number(34),
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
template: Some(vec!["Person".to_string()]), template: Some(vec!["Person".to_string()]),
@@ -624,10 +624,10 @@ mod tests {
assert_eq!(resolved.name, "Martha"); assert_eq!(resolved.name, "Martha");
assert_eq!(resolved.fields.len(), 2); assert_eq!(resolved.fields.len(), 2);
assert_eq!(resolved.fields.get("age"), Some(&Value::Int(34))); assert_eq!(resolved.fields.get("age"), Some(&Value::Number(34)));
assert_eq!( assert_eq!(
resolved.fields.get("type"), resolved.fields.get("type"),
Some(&Value::String("human".to_string())) Some(&Value::Text("human".to_string()))
); );
} }
@@ -639,7 +639,7 @@ mod tests {
name: "Physical".to_string(), name: "Physical".to_string(),
fields: vec![Field { fields: vec![Field {
name: "height".to_string(), name: "height".to_string(),
value: Value::Int(0), value: Value::Number(0),
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
strict: false, strict: false,
@@ -653,7 +653,7 @@ mod tests {
name: "Mental".to_string(), name: "Mental".to_string(),
fields: vec![Field { fields: vec![Field {
name: "iq".to_string(), name: "iq".to_string(),
value: Value::Int(0), value: Value::Number(0),
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
strict: false, strict: false,
@@ -669,12 +669,12 @@ mod tests {
fields: vec![ fields: vec![
Field { Field {
name: "height".to_string(), name: "height".to_string(),
value: Value::Int(165), value: Value::Number(165),
span: Span::new(0, 10), span: Span::new(0, 10),
}, },
Field { Field {
name: "iq".to_string(), name: "iq".to_string(),
value: Value::Int(120), value: Value::Number(120),
span: Span::new(10, 20), span: Span::new(10, 20),
}, },
], ],
@@ -700,8 +700,8 @@ mod tests {
assert_eq!(resolved.name, "Martha"); assert_eq!(resolved.name, "Martha");
assert_eq!(resolved.fields.len(), 2); assert_eq!(resolved.fields.len(), 2);
assert_eq!(resolved.fields.get("height"), Some(&Value::Int(165))); assert_eq!(resolved.fields.get("height"), Some(&Value::Number(165)));
assert_eq!(resolved.fields.get("iq"), Some(&Value::Int(120))); assert_eq!(resolved.fields.get("iq"), Some(&Value::Number(120)));
} }
#[test] #[test]
@@ -712,7 +712,7 @@ mod tests {
name: "Human".to_string(), name: "Human".to_string(),
fields: vec![Field { fields: vec![Field {
name: "type".to_string(), // Changed from "species" name: "type".to_string(), // Changed from "species"
value: Value::String("human".to_string()), value: Value::Text("human".to_string()),
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
strict: false, strict: false,
@@ -726,7 +726,7 @@ mod tests {
name: "Person".to_string(), name: "Person".to_string(),
fields: vec![Field { fields: vec![Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Int(0), value: Value::Number(0),
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
strict: false, strict: false,
@@ -751,10 +751,10 @@ mod tests {
assert_eq!(resolved.name, "Person"); assert_eq!(resolved.name, "Person");
assert_eq!(resolved.fields.len(), 2); assert_eq!(resolved.fields.len(), 2);
assert_eq!(resolved.fields.get("age"), Some(&Value::Int(0))); assert_eq!(resolved.fields.get("age"), Some(&Value::Number(0)));
assert_eq!( assert_eq!(
resolved.fields.get("type"), resolved.fields.get("type"),
Some(&Value::String("human".to_string())) Some(&Value::Text("human".to_string()))
); );
} }
@@ -765,7 +765,7 @@ mod tests {
species: None, species: None,
fields: vec![Field { fields: vec![Field {
name: "species".to_string(), // Reserved keyword! name: "species".to_string(), // Reserved keyword!
value: Value::String("human".to_string()), value: Value::Text("human".to_string()),
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
template: None, template: None,
@@ -793,7 +793,7 @@ mod tests {
name: "Person".to_string(), name: "Person".to_string(),
fields: vec![Field { fields: vec![Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Range(Box::new(Value::Int(18)), Box::new(Value::Int(65))), value: Value::Range(Box::new(Value::Number(18)), Box::new(Value::Number(65))),
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
strict: true, strict: true,

View File

@@ -32,8 +32,8 @@ fn test_simple_character_end_to_end() {
| ResolvedDeclaration::Character(c) => { | ResolvedDeclaration::Character(c) => {
assert_eq!(c.name, "Martha"); assert_eq!(c.name, "Martha");
assert_eq!(c.fields.len(), 2); assert_eq!(c.fields.len(), 2);
assert_eq!(c.fields.get("age"), Some(&Value::Int(34))); assert_eq!(c.fields.get("age"), Some(&Value::Number(34)));
assert_eq!(c.fields.get("health"), Some(&Value::Float(0.8))); assert_eq!(c.fields.get("health"), Some(&Value::Decimal(0.8)));
}, },
| _ => panic!("Expected Character"), | _ => panic!("Expected Character"),
} }
@@ -58,7 +58,7 @@ She loved baking from a young age.
| ResolvedDeclaration::Character(c) => { | ResolvedDeclaration::Character(c) => {
assert_eq!(c.name, "Martha"); assert_eq!(c.name, "Martha");
assert_eq!(c.fields.len(), 1); assert_eq!(c.fields.len(), 1);
assert_eq!(c.fields.get("age"), Some(&Value::Int(34))); assert_eq!(c.fields.get("age"), Some(&Value::Number(34)));
assert_eq!(c.prose_blocks.len(), 1); assert_eq!(c.prose_blocks.len(), 1);
let backstory = c.prose_blocks.get("backstory").unwrap(); let backstory = c.prose_blocks.get("backstory").unwrap();
@@ -108,7 +108,7 @@ fn test_relationship_end_to_end() {
| ResolvedDeclaration::Relationship(r) => { | ResolvedDeclaration::Relationship(r) => {
assert_eq!(r.name, "Spousal"); assert_eq!(r.name, "Spousal");
assert_eq!(r.participants.len(), 2); assert_eq!(r.participants.len(), 2);
assert_eq!(r.fields.get("bond"), Some(&Value::Float(0.9))); assert_eq!(r.fields.get("bond"), Some(&Value::Decimal(0.9)));
}, },
| _ => panic!("Expected Relationship"), | _ => panic!("Expected Relationship"),
} }
@@ -208,8 +208,8 @@ fn test_institution_end_to_end() {
match &resolved[0] { match &resolved[0] {
| ResolvedDeclaration::Institution(i) => { | ResolvedDeclaration::Institution(i) => {
assert_eq!(i.name, "Bakery"); assert_eq!(i.name, "Bakery");
assert_eq!(i.fields.get("employees"), Some(&Value::Int(5))); assert_eq!(i.fields.get("employees"), Some(&Value::Number(5)));
assert_eq!(i.fields.get("revenue"), Some(&Value::Int(50000))); assert_eq!(i.fields.get("revenue"), Some(&Value::Number(50000)));
}, },
| _ => panic!("Expected Institution"), | _ => panic!("Expected Institution"),
} }
@@ -230,8 +230,8 @@ fn test_location_end_to_end() {
match &resolved[0] { match &resolved[0] {
| ResolvedDeclaration::Location(l) => { | ResolvedDeclaration::Location(l) => {
assert_eq!(l.name, "Bakery"); assert_eq!(l.name, "Bakery");
assert_eq!(l.fields.get("x"), Some(&Value::Int(100))); assert_eq!(l.fields.get("x"), Some(&Value::Number(100)));
assert_eq!(l.fields.get("y"), Some(&Value::Int(200))); assert_eq!(l.fields.get("y"), Some(&Value::Number(200)));
}, },
| _ => panic!("Expected Location"), | _ => panic!("Expected Location"),
} }
@@ -252,8 +252,8 @@ fn test_species_end_to_end() {
match &resolved[0] { match &resolved[0] {
| ResolvedDeclaration::Species(s) => { | ResolvedDeclaration::Species(s) => {
assert_eq!(s.name, "Human"); assert_eq!(s.name, "Human");
assert_eq!(s.fields.get("lifespan"), Some(&Value::Int(80))); assert_eq!(s.fields.get("lifespan"), Some(&Value::Number(80)));
assert_eq!(s.fields.get("intelligence"), Some(&Value::Float(0.9))); assert_eq!(s.fields.get("intelligence"), Some(&Value::Decimal(0.9)));
}, },
| _ => panic!("Expected Species"), | _ => panic!("Expected Species"),
} }
@@ -375,12 +375,12 @@ fn test_all_value_types_convert() {
let resolved = parse_and_convert(source).unwrap(); let resolved = parse_and_convert(source).unwrap();
match &resolved[0] { match &resolved[0] {
| ResolvedDeclaration::Character(c) => { | ResolvedDeclaration::Character(c) => {
assert_eq!(c.fields.get("int_val"), Some(&Value::Int(42))); assert_eq!(c.fields.get("int_val"), Some(&Value::Number(42)));
assert_eq!(c.fields.get("float_val"), Some(&Value::Float(3.5))); assert_eq!(c.fields.get("float_val"), Some(&Value::Decimal(3.5)));
assert_eq!(c.fields.get("bool_val"), Some(&Value::Bool(true))); assert_eq!(c.fields.get("bool_val"), Some(&Value::Boolean(true)));
assert_eq!( assert_eq!(
c.fields.get("string_val"), c.fields.get("string_val"),
Some(&Value::String("hello".to_string())) Some(&Value::Text("hello".to_string()))
); );
}, },
| _ => panic!("Expected Character"), | _ => panic!("Expected Character"),

View File

@@ -54,12 +54,12 @@ fn valid_ident() -> impl Strategy<Value = String> {
fn valid_value() -> impl Strategy<Value = Value> { fn valid_value() -> impl Strategy<Value = Value> {
prop_oneof![ prop_oneof![
(-1000i64..1000).prop_map(Value::Int), (-1000i64..1000).prop_map(Value::Number),
(-1000.0..1000.0) (-1000.0..1000.0)
.prop_filter("finite", |f: &f64| f.is_finite()) .prop_filter("finite", |f: &f64| f.is_finite())
.prop_map(Value::Float), .prop_map(Value::Decimal),
any::<bool>().prop_map(Value::Bool), any::<bool>().prop_map(Value::Boolean),
"[a-zA-Z0-9 ]{0,30}".prop_map(Value::String), "[a-zA-Z0-9 ]{0,30}".prop_map(Value::Text),
] ]
} }
@@ -296,22 +296,22 @@ mod edge_cases {
fields: vec![ fields: vec![
Field { Field {
name: "int_field".to_string(), name: "int_field".to_string(),
value: Value::Int(int_val), value: Value::Number(int_val),
span: Span::new(0, 10), span: Span::new(0, 10),
}, },
Field { Field {
name: "float_field".to_string(), name: "float_field".to_string(),
value: Value::Float(float_val), value: Value::Decimal(float_val),
span: Span::new(10, 20), span: Span::new(10, 20),
}, },
Field { Field {
name: "bool_field".to_string(), name: "bool_field".to_string(),
value: Value::Bool(bool_val), value: Value::Boolean(bool_val),
span: Span::new(20, 30), span: Span::new(20, 30),
}, },
Field { Field {
name: "string_field".to_string(), name: "string_field".to_string(),
value: Value::String(string_val.clone()), value: Value::Text(string_val.clone()),
span: Span::new(30, 40), span: Span::new(30, 40),
}, },
], ],
@@ -322,10 +322,10 @@ mod edge_cases {
}; };
let resolved = convert_character(&character).unwrap(); let resolved = convert_character(&character).unwrap();
assert_eq!(resolved.fields.get("int_field"), Some(&Value::Int(int_val))); assert_eq!(resolved.fields.get("int_field"), Some(&Value::Number(int_val)));
assert_eq!(resolved.fields.get("float_field"), Some(&Value::Float(float_val))); assert_eq!(resolved.fields.get("float_field"), Some(&Value::Decimal(float_val)));
assert_eq!(resolved.fields.get("bool_field"), Some(&Value::Bool(bool_val))); assert_eq!(resolved.fields.get("bool_field"), Some(&Value::Boolean(bool_val)));
assert_eq!(resolved.fields.get("string_field"), Some(&Value::String(string_val))); assert_eq!(resolved.fields.get("string_field"), Some(&Value::Text(string_val)));
} }
#[test] #[test]
@@ -341,7 +341,7 @@ mod edge_cases {
species: None, species: None,
fields: vec![Field { fields: vec![Field {
name: field_name.clone(), name: field_name.clone(),
value: Value::String(string_val.clone()), value: Value::Text(string_val.clone()),
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
template: None, template: None,
@@ -354,7 +354,7 @@ mod edge_cases {
assert_eq!(resolved.name, name); assert_eq!(resolved.name, name);
assert_eq!( assert_eq!(
resolved.fields.get(&field_name), resolved.fields.get(&field_name),
Some(&Value::String(string_val)) Some(&Value::Text(string_val))
); );
} }
} }

View File

@@ -194,7 +194,7 @@ mod tests {
fn make_field(name: &str, value: i64) -> Field { fn make_field(name: &str, value: i64) -> Field {
Field { Field {
name: name.to_string(), name: name.to_string(),
value: Value::Int(value), value: Value::Number(value),
span: Span::new(0, 10), span: Span::new(0, 10),
} }
} }

View File

@@ -48,7 +48,7 @@ fn valid_ident() -> impl Strategy<Value = String> {
fn valid_field() -> impl Strategy<Value = Field> { fn valid_field() -> impl Strategy<Value = Field> {
(valid_ident(), 0i64..100).prop_map(|(name, value)| Field { (valid_ident(), 0i64..100).prop_map(|(name, value)| Field {
name, name,
value: Value::Int(value), value: Value::Number(value),
span: Span::new(0, 10), span: Span::new(0, 10),
}) })
} }

View File

@@ -430,7 +430,7 @@ mod tests {
fn make_field(name: &str, value: i64) -> Field { fn make_field(name: &str, value: i64) -> Field {
Field { Field {
name: name.to_string(), name: name.to_string(),
value: Value::Int(value), value: Value::Number(value),
span: Span::new(0, 10), span: Span::new(0, 10),
} }
} }
@@ -445,7 +445,7 @@ mod tests {
assert_eq!(result.len(), 2); assert_eq!(result.len(), 2);
let age_field = result.iter().find(|f| f.name == "age").unwrap(); let age_field = result.iter().find(|f| f.name == "age").unwrap();
assert_eq!(age_field.value, Value::Int(30)); assert_eq!(age_field.value, Value::Number(30));
} }
#[test] #[test]
@@ -526,7 +526,7 @@ mod tests {
assert_eq!(result.len(), 3); assert_eq!(result.len(), 3);
let age = result.iter().find(|f| f.name == "age").unwrap(); let age = result.iter().find(|f| f.name == "age").unwrap();
assert_eq!(age.value, Value::Int(30)); assert_eq!(age.value, Value::Number(30));
assert!(!result.iter().any(|f| f.name == "energy")); assert!(!result.iter().any(|f| f.name == "energy"));
assert!(result.iter().any(|f| f.name == "strength")); assert!(result.iter().any(|f| f.name == "strength"));
@@ -612,7 +612,7 @@ mod tests {
assert_eq!(result.len(), 1); assert_eq!(result.len(), 1);
assert_eq!(result[0].name, "age"); assert_eq!(result[0].name, "age");
assert_eq!(result[0].value, Value::Int(25)); assert_eq!(result[0].value, Value::Number(25));
} }
#[test] #[test]
@@ -682,8 +682,8 @@ mod tests {
assert_eq!(result.len(), 1); assert_eq!(result.len(), 1);
assert_eq!(result[0].name, "age"); assert_eq!(result[0].name, "age");
assert_eq!(result[0].value, Value::Int(25)); // Should be overridden assert_eq!(result[0].value, Value::Number(25)); // Should be overridden
// value // value
} }
#[test] #[test]
@@ -702,8 +702,8 @@ mod tests {
assert_eq!(result.len(), 1); assert_eq!(result.len(), 1);
assert_eq!(result[0].name, "age"); assert_eq!(result[0].name, "age");
assert_eq!(result[0].value, Value::Int(34)); // Character's value assert_eq!(result[0].value, Value::Number(34)); // Character's value
// overrides template // overrides template
} }
#[test] #[test]
@@ -729,10 +729,10 @@ mod tests {
assert_eq!(result.len(), 2); assert_eq!(result.len(), 2);
assert!(result assert!(result
.iter() .iter()
.any(|f| f.name == "height" && f.value == Value::Int(165))); .any(|f| f.name == "height" && f.value == Value::Number(165)));
assert!(result assert!(result
.iter() .iter()
.any(|f| f.name == "iq" && f.value == Value::Int(120))); .any(|f| f.name == "iq" && f.value == Value::Number(120)));
} }
#[test] #[test]
@@ -758,10 +758,10 @@ mod tests {
assert_eq!(result.len(), 2); assert_eq!(result.len(), 2);
assert!(result assert!(result
.iter() .iter()
.any(|f| f.name == "age" && f.value == Value::Int(34))); .any(|f| f.name == "age" && f.value == Value::Number(34)));
assert!(result assert!(result
.iter() .iter()
.any(|f| f.name == "name" && f.value == Value::Int(1))); .any(|f| f.name == "name" && f.value == Value::Number(1)));
} }
#[test] #[test]
@@ -786,7 +786,7 @@ mod tests {
"Person", "Person",
vec![Field { vec![Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Range(Box::new(Value::Int(18)), Box::new(Value::Int(65))), value: Value::Range(Box::new(Value::Number(18)), Box::new(Value::Number(65))),
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
vec![], vec![],
@@ -837,7 +837,7 @@ mod tests {
assert_eq!(result.len(), 2); assert_eq!(result.len(), 2);
let age = result.iter().find(|f| f.name == "age").unwrap(); let age = result.iter().find(|f| f.name == "age").unwrap();
assert_eq!(age.value, Value::Int(30)); assert_eq!(age.value, Value::Number(30));
} }
#[test] #[test]

View File

@@ -19,7 +19,7 @@ fn valid_ident() -> impl Strategy<Value = String> {
fn valid_field() -> impl Strategy<Value = Field> { fn valid_field() -> impl Strategy<Value = Field> {
(valid_ident(), 0i64..1000).prop_map(|(name, value)| Field { (valid_ident(), 0i64..1000).prop_map(|(name, value)| Field {
name, name,
value: Value::Int(value), value: Value::Number(value),
span: Span::new(0, 10), span: Span::new(0, 10),
}) })
} }
@@ -186,12 +186,12 @@ proptest! {
) { ) {
let field1 = Field { let field1 = Field {
name: name.clone(), name: name.clone(),
value: Value::Int(val1), value: Value::Number(val1),
span: Span::new(0, 10), span: Span::new(0, 10),
}; };
let field2 = Field { let field2 = Field {
name: name.clone(), name: name.clone(),
value: Value::Int(val2), value: Value::Number(val2),
span: Span::new(0, 10), span: Span::new(0, 10),
}; };
@@ -251,12 +251,12 @@ proptest! {
) { ) {
let field1 = Field { let field1 = Field {
name: name.clone(), name: name.clone(),
value: Value::Int(val1), value: Value::Number(val1),
span: Span::new(0, 10), span: Span::new(0, 10),
}; };
let field2 = Field { let field2 = Field {
name: name.clone(), name: name.clone(),
value: Value::Int(val2), value: Value::Number(val2),
span: Span::new(0, 10), span: Span::new(0, 10),
}; };
@@ -277,8 +277,8 @@ proptest! {
let value1 = result1.iter().find(|f| f.name == name).unwrap().value.clone(); let value1 = result1.iter().find(|f| f.name == name).unwrap().value.clone();
let value2 = result2.iter().find(|f| f.name == name).unwrap().value.clone(); let value2 = result2.iter().find(|f| f.name == name).unwrap().value.clone();
assert_eq!(value1, Value::Int(val2)); assert_eq!(value1, Value::Number(val2));
assert_eq!(value2, Value::Int(val1)); assert_eq!(value2, Value::Number(val1));
} }
#[test] #[test]

View File

@@ -83,7 +83,7 @@ pub fn validate_no_reserved_keywords(fields: &[Field], collector: &mut ErrorColl
pub fn validate_trait_ranges(fields: &[Field], collector: &mut ErrorCollector) { pub fn validate_trait_ranges(fields: &[Field], collector: &mut ErrorCollector) {
for field in fields { for field in fields {
match &field.value { match &field.value {
| Value::Float(f) => { | Value::Decimal(f) => {
// Normalized trait values should be 0.0 .. 1.0 // Normalized trait values should be 0.0 .. 1.0
if (field.name.ends_with("_normalized") || if (field.name.ends_with("_normalized") ||
field.name == "bond" || field.name == "bond" ||
@@ -99,7 +99,7 @@ pub fn validate_trait_ranges(fields: &[Field], collector: &mut ErrorCollector) {
}); });
} }
}, },
| Value::Int(i) => { | Value::Number(i) => {
// Age should be reasonable // Age should be reasonable
if field.name == "age" && (*i < 0 || *i > 150) { if field.name == "age" && (*i < 0 || *i > 150) {
collector.add(ResolveError::TraitOutOfRange { collector.add(ResolveError::TraitOutOfRange {
@@ -120,7 +120,7 @@ pub fn validate_relationship_bonds(relationships: &[Relationship], collector: &m
for rel in relationships { for rel in relationships {
for field in &rel.fields { for field in &rel.fields {
if field.name == "bond" { if field.name == "bond" {
if let Value::Float(f) = field.value { if let Value::Decimal(f) = field.value {
if !(0.0..=1.0).contains(&f) { if !(0.0..=1.0).contains(&f) {
collector.add(ResolveError::TraitOutOfRange { collector.add(ResolveError::TraitOutOfRange {
field: "bond".to_string(), field: "bond".to_string(),
@@ -457,12 +457,12 @@ mod tests {
let fields = vec![ let fields = vec![
Field { Field {
name: "bond".to_string(), name: "bond".to_string(),
value: Value::Float(0.8), value: Value::Decimal(0.8),
span: Span::new(0, 10), span: Span::new(0, 10),
}, },
Field { Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Int(30), value: Value::Number(30),
span: Span::new(0, 10), span: Span::new(0, 10),
}, },
]; ];
@@ -476,7 +476,7 @@ mod tests {
fn test_invalid_bond_value_too_high() { fn test_invalid_bond_value_too_high() {
let fields = vec![Field { let fields = vec![Field {
name: "bond".to_string(), name: "bond".to_string(),
value: Value::Float(1.5), value: Value::Decimal(1.5),
span: Span::new(0, 10), span: Span::new(0, 10),
}]; }];
@@ -489,7 +489,7 @@ mod tests {
fn test_invalid_bond_value_negative() { fn test_invalid_bond_value_negative() {
let fields = vec![Field { let fields = vec![Field {
name: "bond".to_string(), name: "bond".to_string(),
value: Value::Float(-0.1), value: Value::Decimal(-0.1),
span: Span::new(0, 10), span: Span::new(0, 10),
}]; }];
@@ -502,7 +502,7 @@ mod tests {
fn test_invalid_age_negative() { fn test_invalid_age_negative() {
let fields = vec![Field { let fields = vec![Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Int(-5), value: Value::Number(-5),
span: Span::new(0, 10), span: Span::new(0, 10),
}]; }];
@@ -515,7 +515,7 @@ mod tests {
fn test_invalid_age_too_high() { fn test_invalid_age_too_high() {
let fields = vec![Field { let fields = vec![Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Int(200), value: Value::Number(200),
span: Span::new(0, 10), span: Span::new(0, 10),
}]; }];
@@ -531,7 +531,7 @@ mod tests {
participants: vec![], participants: vec![],
fields: vec![Field { fields: vec![Field {
name: "bond".to_string(), name: "bond".to_string(),
value: Value::Float(0.9), value: Value::Decimal(0.9),
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
span: Span::new(0, 100), span: Span::new(0, 100),
@@ -549,7 +549,7 @@ mod tests {
participants: vec![], participants: vec![],
fields: vec![Field { fields: vec![Field {
name: "bond".to_string(), name: "bond".to_string(),
value: Value::Float(1.2), value: Value::Decimal(1.2),
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
span: Span::new(0, 100), span: Span::new(0, 100),

View File

@@ -17,7 +17,7 @@ use crate::{
fn valid_bond_field() -> impl Strategy<Value = Field> { fn valid_bond_field() -> impl Strategy<Value = Field> {
(0.0..=1.0).prop_map(|f| Field { (0.0..=1.0).prop_map(|f| Field {
name: "bond".to_string(), name: "bond".to_string(),
value: Value::Float(f), value: Value::Decimal(f),
span: Span::new(0, 10), span: Span::new(0, 10),
}) })
} }
@@ -26,12 +26,12 @@ fn invalid_bond_field() -> impl Strategy<Value = Field> {
prop_oneof![ prop_oneof![
(-100.0..0.0).prop_map(|f| Field { (-100.0..0.0).prop_map(|f| Field {
name: "bond".to_string(), name: "bond".to_string(),
value: Value::Float(f), value: Value::Decimal(f),
span: Span::new(0, 10), span: Span::new(0, 10),
}), }),
(1.0..100.0).prop_map(|f| Field { (1.0..100.0).prop_map(|f| Field {
name: "bond".to_string(), name: "bond".to_string(),
value: Value::Float(f), value: Value::Decimal(f),
span: Span::new(0, 10), span: Span::new(0, 10),
}), }),
] ]
@@ -40,7 +40,7 @@ fn invalid_bond_field() -> impl Strategy<Value = Field> {
fn valid_age_field() -> impl Strategy<Value = Field> { fn valid_age_field() -> impl Strategy<Value = Field> {
(0i64..=150).prop_map(|age| Field { (0i64..=150).prop_map(|age| Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Int(age), value: Value::Number(age),
span: Span::new(0, 10), span: Span::new(0, 10),
}) })
} }
@@ -49,12 +49,12 @@ fn invalid_age_field() -> impl Strategy<Value = Field> {
prop_oneof![ prop_oneof![
(-100i64..-1).prop_map(|age| Field { (-100i64..-1).prop_map(|age| Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Int(age), value: Value::Number(age),
span: Span::new(0, 10), span: Span::new(0, 10),
}), }),
(151i64..300).prop_map(|age| Field { (151i64..300).prop_map(|age| Field {
name: "age".to_string(), name: "age".to_string(),
value: Value::Int(age), value: Value::Number(age),
span: Span::new(0, 10), span: Span::new(0, 10),
}), }),
] ]
@@ -99,7 +99,7 @@ proptest! {
fn test_bond_exact_bounds(f in 0.0f64..=1.0) { fn test_bond_exact_bounds(f in 0.0f64..=1.0) {
let field = Field { let field = Field {
name: "bond".to_string(), name: "bond".to_string(),
value: Value::Float(f), value: Value::Decimal(f),
span: Span::new(0, 10), span: Span::new(0, 10),
}; };
let mut collector = ErrorCollector::new(); let mut collector = ErrorCollector::new();
@@ -116,7 +116,7 @@ proptest! {
participants: vec![], participants: vec![],
fields: vec![Field { fields: vec![Field {
name: "bond".to_string(), name: "bond".to_string(),
value: Value::Float(bond_value), value: Value::Decimal(bond_value),
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
span: Span::new(0, 100), span: Span::new(0, 100),
@@ -136,7 +136,7 @@ proptest! {
participants: vec![], participants: vec![],
fields: vec![Field { fields: vec![Field {
name: "bond".to_string(), name: "bond".to_string(),
value: Value::Float(bond_value), value: Value::Decimal(bond_value),
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
span: Span::new(0, 100), span: Span::new(0, 100),
@@ -164,7 +164,7 @@ proptest! {
on_enter: None, on_enter: None,
transitions: vec![Transition { transitions: vec![Transition {
to: state2_name.clone(), to: state2_name.clone(),
condition: Expr::BoolLit(true), condition: Expr::BooleanLit(true),
span: Span::new(0, 10), span: Span::new(0, 10),
}], }],
span: Span::new(0, 50), span: Span::new(0, 50),

View File

@@ -158,10 +158,10 @@ pub struct Field {
/// Field value types /// Field value types
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum Value { pub enum Value {
Int(i64), Number(i64),
Float(f64), Decimal(f64),
String(String), Text(String),
Bool(bool), Boolean(bool),
Range(Box<Value>, Box<Value>), // For templates: 20..40 Range(Box<Value>, Box<Value>), // For templates: 20..40
Time(Time), Time(Time),
Duration(Duration), Duration(Duration),
@@ -466,10 +466,10 @@ pub enum Condition {
/// Expression AST for conditions and queries /// Expression AST for conditions and queries
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum Expr { pub enum Expr {
IntLit(i64), NumberLit(i64),
FloatLit(f64), DecimalLit(f64),
StringLit(String), TextLit(String),
BoolLit(bool), BooleanLit(bool),
Identifier(Vec<String>), Identifier(Vec<String>),
FieldAccess(Box<Expr>, String), FieldAccess(Box<Expr>, String),
Comparison(Box<Expr>, CompOp, Box<Expr>), Comparison(Box<Expr>, CompOp, Box<Expr>),

View File

@@ -244,18 +244,18 @@ Field: Field = {
}; };
Value: Value = { Value: Value = {
<NumberLit> => Value::Int(<>), <NumberLit> => Value::Number(<>),
<DecimalLit> => Value::Float(<>), <DecimalLit> => Value::Decimal(<>),
<TextLit> => Value::String(<>), <TextLit> => Value::Text(<>),
<BoolLit> => Value::Bool(<>), <BoolLit> => Value::Boolean(<>),
"any" => Value::Any, "any" => Value::Any,
<lo:NumberLit> ".." <hi:NumberLit> => Value::Range( <lo:NumberLit> ".." <hi:NumberLit> => Value::Range(
Box::new(Value::Int(lo)), Box::new(Value::Number(lo)),
Box::new(Value::Int(hi)) Box::new(Value::Number(hi))
), ),
<lo:DecimalLit> ".." <hi:DecimalLit> => Value::Range( <lo:DecimalLit> ".." <hi:DecimalLit> => Value::Range(
Box::new(Value::Float(lo)), Box::new(Value::Decimal(lo)),
Box::new(Value::Float(hi)) Box::new(Value::Decimal(hi))
), ),
<t:Time> => Value::Time(t), <t:Time> => Value::Time(t),
<d:Duration> => Value::Duration(d), <d:Duration> => Value::Duration(d),
@@ -949,10 +949,10 @@ InequalityOp: CompOp = {
}; };
Literal: Expr = { Literal: Expr = {
<NumberLit> => Expr::IntLit(<>), <NumberLit> => Expr::NumberLit(<>),
<DecimalLit> => Expr::FloatLit(<>), <DecimalLit> => Expr::DecimalLit(<>),
<TextLit> => Expr::StringLit(<>), <TextLit> => Expr::TextLit(<>),
<BoolLit> => Expr::BoolLit(<>), <BoolLit> => Expr::BooleanLit(<>),
}; };
// ===== Helpers ===== // ===== Helpers =====

View File

@@ -1,5 +1,5 @@
// auto-generated: "lalrpop 0.21.0" // auto-generated: "lalrpop 0.21.0"
// sha3: 74aa329f2c008adb120b171834cf36dcc8e33b949ab1a2fe8bd5e54d42b398af // sha3: 18bbe1925e11ceeec53b1eb8484775a415600ddf99220fba53d408b46198a3aa
use crate::syntax::{ use crate::syntax::{
ast::*, ast::*,
lexer::Token, lexer::Token,
@@ -13528,7 +13528,7 @@ fn __action46((_, pb, _): (usize, ProseBlock, usize)) -> Field {
clippy::just_underscores_and_digits clippy::just_underscores_and_digits
)] )]
fn __action47((_, __0, _): (usize, i64, usize)) -> Value { fn __action47((_, __0, _): (usize, i64, usize)) -> Value {
Value::Int(__0) Value::Number(__0)
} }
#[allow( #[allow(
@@ -13537,7 +13537,7 @@ fn __action47((_, __0, _): (usize, i64, usize)) -> Value {
clippy::just_underscores_and_digits clippy::just_underscores_and_digits
)] )]
fn __action48((_, __0, _): (usize, f64, usize)) -> Value { fn __action48((_, __0, _): (usize, f64, usize)) -> Value {
Value::Float(__0) Value::Decimal(__0)
} }
#[allow( #[allow(
@@ -13546,7 +13546,7 @@ fn __action48((_, __0, _): (usize, f64, usize)) -> Value {
clippy::just_underscores_and_digits clippy::just_underscores_and_digits
)] )]
fn __action49((_, __0, _): (usize, String, usize)) -> Value { fn __action49((_, __0, _): (usize, String, usize)) -> Value {
Value::String(__0) Value::Text(__0)
} }
#[allow( #[allow(
@@ -13555,7 +13555,7 @@ fn __action49((_, __0, _): (usize, String, usize)) -> Value {
clippy::just_underscores_and_digits clippy::just_underscores_and_digits
)] )]
fn __action50((_, __0, _): (usize, bool, usize)) -> Value { fn __action50((_, __0, _): (usize, bool, usize)) -> Value {
Value::Bool(__0) Value::Boolean(__0)
} }
#[allow( #[allow(
@@ -13577,7 +13577,7 @@ fn __action52(
(_, _, _): (usize, Token, usize), (_, _, _): (usize, Token, usize),
(_, hi, _): (usize, i64, usize), (_, hi, _): (usize, i64, usize),
) -> Value { ) -> Value {
Value::Range(Box::new(Value::Int(lo)), Box::new(Value::Int(hi))) Value::Range(Box::new(Value::Number(lo)), Box::new(Value::Number(hi)))
} }
#[allow( #[allow(
@@ -13590,7 +13590,7 @@ fn __action53(
(_, _, _): (usize, Token, usize), (_, _, _): (usize, Token, usize),
(_, hi, _): (usize, f64, usize), (_, hi, _): (usize, f64, usize),
) -> Value { ) -> Value {
Value::Range(Box::new(Value::Float(lo)), Box::new(Value::Float(hi))) Value::Range(Box::new(Value::Decimal(lo)), Box::new(Value::Decimal(hi)))
} }
#[allow( #[allow(
@@ -15225,7 +15225,7 @@ fn __action161((_, __0, _): (usize, Token, usize)) -> CompOp {
clippy::just_underscores_and_digits clippy::just_underscores_and_digits
)] )]
fn __action162((_, __0, _): (usize, i64, usize)) -> Expr { fn __action162((_, __0, _): (usize, i64, usize)) -> Expr {
Expr::IntLit(__0) Expr::NumberLit(__0)
} }
#[allow( #[allow(
@@ -15234,7 +15234,7 @@ fn __action162((_, __0, _): (usize, i64, usize)) -> Expr {
clippy::just_underscores_and_digits clippy::just_underscores_and_digits
)] )]
fn __action163((_, __0, _): (usize, f64, usize)) -> Expr { fn __action163((_, __0, _): (usize, f64, usize)) -> Expr {
Expr::FloatLit(__0) Expr::DecimalLit(__0)
} }
#[allow( #[allow(
@@ -15243,7 +15243,7 @@ fn __action163((_, __0, _): (usize, f64, usize)) -> Expr {
clippy::just_underscores_and_digits clippy::just_underscores_and_digits
)] )]
fn __action164((_, __0, _): (usize, String, usize)) -> Expr { fn __action164((_, __0, _): (usize, String, usize)) -> Expr {
Expr::StringLit(__0) Expr::TextLit(__0)
} }
#[allow( #[allow(
@@ -15252,7 +15252,7 @@ fn __action164((_, __0, _): (usize, String, usize)) -> Expr {
clippy::just_underscores_and_digits clippy::just_underscores_and_digits
)] )]
fn __action165((_, __0, _): (usize, bool, usize)) -> Expr { fn __action165((_, __0, _): (usize, bool, usize)) -> Expr {
Expr::BoolLit(__0) Expr::BooleanLit(__0)
} }
#[allow( #[allow(

View File

@@ -73,10 +73,10 @@ fn character_editor_view<'a>(editor: &'a Editor, char_name: &str) -> Element<'a,
// Show all fields with soft metadata styling // Show all fields with soft metadata styling
for (field_name, field_value) in &char.fields { for (field_name, field_value) in &char.fields {
let value_text = match field_value { let value_text = match field_value {
| Value::Int(n) => format!("{}", n), | Value::Number(n) => format!("{}", n),
| Value::Float(n) => format!("{}", n), | Value::Decimal(n) => format!("{}", n),
| Value::String(s) => s.clone(), | Value::Text(s) => s.clone(),
| Value::Bool(b) => format!("{}", b), | Value::Boolean(b) => format!("{}", b),
| Value::List(items) => { | Value::List(items) => {
format!("[{} items]", items.len()) format!("[{} items]", items.len())
}, },

View File

@@ -106,15 +106,15 @@ fn test_baker_family_field_values() {
let martha = project.find_character("Martha").unwrap(); let martha = project.find_character("Martha").unwrap();
// Martha sets age: 34 (overriding Person template range 0..100) // Martha sets age: 34 (overriding Person template range 0..100)
if let Some(storybook::syntax::ast::Value::Int(age)) = martha.fields.get("age") { if let Some(storybook::syntax::ast::Value::Number(age)) = martha.fields.get("age") {
assert_eq!(*age, 34, "Martha's age should be 34"); assert_eq!(*age, 34, "Martha's age should be 34");
} else { } else {
panic!("age should be an Int"); panic!("age should be a Number");
} }
// Martha sets specialty: "sourdough" (overriding Baker template default // Martha sets specialty: "sourdough" (overriding Baker template default
// "bread") // "bread")
if let Some(storybook::syntax::ast::Value::String(specialty)) = martha.fields.get("specialty") { if let Some(storybook::syntax::ast::Value::Text(specialty)) = martha.fields.get("specialty") {
assert_eq!( assert_eq!(
specialty, "sourdough", specialty, "sourdough",
"Martha's specialty should be sourdough" "Martha's specialty should be sourdough"