feat: add JSON parsing and manipulation support
Add comprehensive JSON support via the Json module: - Parse JSON strings with Json.parse() returning Result<Json, String> - Stringify with Json.stringify() and Json.prettyPrint() - Extract values with Json.get(), getIndex(), asString(), asInt(), etc. - Build JSON with constructors: Json.null(), bool(), int(), string(), array(), object() - Query with Json.isNull() and Json.keys() Includes example at examples/json.lux demonstrating building, parsing, and extracting JSON data with file I/O integration. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
147
src/types.rs
147
src/types.rs
@@ -732,6 +732,37 @@ impl TypeEnv {
|
||||
]),
|
||||
);
|
||||
|
||||
// Add Json type (represents JSON values)
|
||||
env.types.insert(
|
||||
"Json".to_string(),
|
||||
TypeDef::Enum(vec![
|
||||
VariantDef {
|
||||
name: "JsonNull".to_string(),
|
||||
fields: VariantFieldsDef::Unit,
|
||||
},
|
||||
VariantDef {
|
||||
name: "JsonBool".to_string(),
|
||||
fields: VariantFieldsDef::Tuple(vec![Type::Bool]),
|
||||
},
|
||||
VariantDef {
|
||||
name: "JsonNumber".to_string(),
|
||||
fields: VariantFieldsDef::Tuple(vec![Type::Float]),
|
||||
},
|
||||
VariantDef {
|
||||
name: "JsonString".to_string(),
|
||||
fields: VariantFieldsDef::Tuple(vec![Type::String]),
|
||||
},
|
||||
VariantDef {
|
||||
name: "JsonArray".to_string(),
|
||||
fields: VariantFieldsDef::Tuple(vec![Type::List(Box::new(Type::Named("Json".to_string())))]),
|
||||
},
|
||||
VariantDef {
|
||||
name: "JsonObject".to_string(),
|
||||
fields: VariantFieldsDef::Tuple(vec![Type::List(Box::new(Type::Tuple(vec![Type::String, Type::Named("Json".to_string())])))]),
|
||||
},
|
||||
]),
|
||||
);
|
||||
|
||||
// Add Console effect
|
||||
env.effects.insert(
|
||||
"Console".to_string(),
|
||||
@@ -1191,6 +1222,122 @@ impl TypeEnv {
|
||||
]);
|
||||
env.bind("String", TypeScheme::mono(string_module_type));
|
||||
|
||||
// Json module
|
||||
let json_type = Type::Named("Json".to_string());
|
||||
let json_module_type = Type::Record(vec![
|
||||
(
|
||||
"parse".to_string(),
|
||||
Type::function(
|
||||
vec![Type::String],
|
||||
Type::App {
|
||||
constructor: Box::new(Type::Named("Result".to_string())),
|
||||
args: vec![json_type.clone(), Type::String],
|
||||
},
|
||||
),
|
||||
),
|
||||
(
|
||||
"stringify".to_string(),
|
||||
Type::function(vec![json_type.clone()], Type::String),
|
||||
),
|
||||
(
|
||||
"prettyPrint".to_string(),
|
||||
Type::function(vec![json_type.clone()], Type::String),
|
||||
),
|
||||
(
|
||||
"get".to_string(),
|
||||
Type::function(
|
||||
vec![json_type.clone(), Type::String],
|
||||
Type::Option(Box::new(json_type.clone())),
|
||||
),
|
||||
),
|
||||
(
|
||||
"getIndex".to_string(),
|
||||
Type::function(
|
||||
vec![json_type.clone(), Type::Int],
|
||||
Type::Option(Box::new(json_type.clone())),
|
||||
),
|
||||
),
|
||||
(
|
||||
"asString".to_string(),
|
||||
Type::function(
|
||||
vec![json_type.clone()],
|
||||
Type::Option(Box::new(Type::String)),
|
||||
),
|
||||
),
|
||||
(
|
||||
"asNumber".to_string(),
|
||||
Type::function(
|
||||
vec![json_type.clone()],
|
||||
Type::Option(Box::new(Type::Float)),
|
||||
),
|
||||
),
|
||||
(
|
||||
"asInt".to_string(),
|
||||
Type::function(
|
||||
vec![json_type.clone()],
|
||||
Type::Option(Box::new(Type::Int)),
|
||||
),
|
||||
),
|
||||
(
|
||||
"asBool".to_string(),
|
||||
Type::function(
|
||||
vec![json_type.clone()],
|
||||
Type::Option(Box::new(Type::Bool)),
|
||||
),
|
||||
),
|
||||
(
|
||||
"asArray".to_string(),
|
||||
Type::function(
|
||||
vec![json_type.clone()],
|
||||
Type::Option(Box::new(Type::List(Box::new(json_type.clone())))),
|
||||
),
|
||||
),
|
||||
(
|
||||
"isNull".to_string(),
|
||||
Type::function(vec![json_type.clone()], Type::Bool),
|
||||
),
|
||||
(
|
||||
"keys".to_string(),
|
||||
Type::function(
|
||||
vec![json_type.clone()],
|
||||
Type::List(Box::new(Type::String)),
|
||||
),
|
||||
),
|
||||
// Constructors for building JSON
|
||||
(
|
||||
"null".to_string(),
|
||||
Type::function(vec![], json_type.clone()),
|
||||
),
|
||||
(
|
||||
"bool".to_string(),
|
||||
Type::function(vec![Type::Bool], json_type.clone()),
|
||||
),
|
||||
(
|
||||
"number".to_string(),
|
||||
Type::function(vec![Type::Float], json_type.clone()),
|
||||
),
|
||||
(
|
||||
"int".to_string(),
|
||||
Type::function(vec![Type::Int], json_type.clone()),
|
||||
),
|
||||
(
|
||||
"string".to_string(),
|
||||
Type::function(vec![Type::String], json_type.clone()),
|
||||
),
|
||||
(
|
||||
"array".to_string(),
|
||||
Type::function(vec![Type::List(Box::new(json_type.clone()))], json_type.clone()),
|
||||
),
|
||||
(
|
||||
"object".to_string(),
|
||||
Type::function(
|
||||
vec![Type::List(Box::new(Type::Tuple(vec![Type::String, json_type.clone()])))],
|
||||
json_type.clone(),
|
||||
),
|
||||
),
|
||||
]);
|
||||
env.bind("Json", TypeScheme::mono(json_module_type));
|
||||
|
||||
// Option module
|
||||
let option_module_type = Type::Record(vec![
|
||||
(
|
||||
|
||||
Reference in New Issue
Block a user