use mortar_compiler::{Deserializer, MortaredData};
use serde_json::Value;
fn main() -> Result<(), String> {
println!("=== Mortar 反序列化示例 ===\n");
let test_json = r#"{
"metadata": {
"version": "0.5.0",
"generated_at": "2025-11-23T00:00:00Z"
},
"variables": [
{ "name": "player_name", "type": "String" },
{ "name": "score", "type": "Number", "value": 0 }
],
"constants": [
{ "name": "MAX_LEVEL", "type": "Number", "value": 99, "public": true }
],
"enums": [
{ "name": "GameState", "variants": ["menu", "playing", "paused"] }
],
"nodes": [
{
"name": "Start",
"content": [
{
"type": "text",
"value": "欢迎来到游戏世界!",
"events": [
{
"index": 0.0,
"actions": [
{ "type": "play_music", "args": ["intro.mp3"] }
]
}
]
},
{
"type": "text",
"value": "你准备好开始冒险了吗?"
},
{
"type": "choice",
"options": [
{ "text": "是的,开始!", "next": "GameStart" },
{ "text": "让我再想想", "action": "break" }
]
}
],
"next": "MainMenu"
},
{
"name": "GameStart",
"content": [
{ "type": "text", "value": "游戏开始!祝你好运。" }
]
},
{
"name": "MainMenu",
"content": [
{ "type": "text", "value": "主菜单" }
]
}
],
"functions": [
{
"name": "play_music",
"params": [ { "name": "file", "type": "String" } ]
},
{
"name": "get_player_name",
"params": [],
"return": "String"
}
]
}"#;
println!("1. 从 JSON 字符串加载数据...");
let data = Deserializer::from_json(test_json)?;
print_basic_info(&data);
println!("\n2. 访问节点信息:");
access_nodes(&data);
println!("\n3. 访问函数声明:");
access_functions(&data);
println!("\n4. 访问变量和常量:");
access_variables_constants(&data);
println!("\n5. 访问枚举:");
access_enums(&data);
println!("\n6. 模拟简单的对话系统:");
simulate_dialogue(&data);
Ok(())
}
fn print_basic_info(data: &MortaredData) {
println!(" 编译器版本: {}", data.metadata.version);
println!(" 生成时间: {}", data.metadata.generated_at);
println!(" 节点数量: {}", data.nodes.len());
println!(" 函数数量: {}", data.functions.len());
println!(" 变量数量: {}", data.variables.len());
println!(" 常量数量: {}", data.constants.len());
println!(" 枚举数量: {}", data.enums.len());
}
fn print_text_content(item_value: &Value, index: usize) {
let text = item_value
.get("value")
.and_then(Value::as_str)
.unwrap_or("");
println!(" 内容 {}: [文本] {}", index + 1, text);
let Some(events) = item_value.get("events").and_then(Value::as_array) else {
return;
};
for event in events {
let index = event.get("index").and_then(Value::as_f64).unwrap_or(0.0);
println!(" 事件 @ {}", index);
let Some(actions) = event.get("actions").and_then(Value::as_array) else {
continue;
};
for action in actions {
let action_type = action.get("type").and_then(Value::as_str).unwrap_or("");
let args = action
.get("args")
.and_then(Value::as_array)
.cloned()
.unwrap_or_default();
println!(" - {}({:?})", action_type, args);
}
}
}
fn print_choice_content(item_value: &Value, index: usize) {
println!(" 内容 {}: [选项]", index + 1);
let Some(options) = item_value.get("options").and_then(Value::as_array) else {
return;
};
for (opt_idx, choice) in options.iter().enumerate() {
let text = choice.get("text").and_then(Value::as_str).unwrap_or("");
print!(" {}. {}", opt_idx + 1, text);
if let Some(next) = choice.get("next").and_then(Value::as_str) {
print!(" -> {}", next);
}
if let Some(action) = choice.get("action").and_then(Value::as_str) {
print!(" [{}]", action);
}
println!();
}
}
fn access_nodes(data: &MortaredData) {
let node_names = data.node_names();
println!(" 所有节点: {:?}", node_names);
let Some(node) = data.get_node("Start") else {
return;
};
println!("\n 节点 '{}' 详情:", node.name);
for (i, item_value) in node.content.iter().enumerate() {
let item_type = item_value.get("type").and_then(Value::as_str).unwrap_or("");
match item_type {
"text" => print_text_content(item_value, i),
"choice" => print_choice_content(item_value, i),
"run_event" => {
let name = item_value.get("name").and_then(Value::as_str).unwrap_or("");
println!(" 内容 {}: [运行事件] {}", i + 1, name);
}
_ => {
println!(" 内容 {}: [未知类型]", i + 1);
}
}
}
if let Some(next) = &node.next {
println!(" 默认跳转: {}", next);
}
}
fn access_functions(data: &MortaredData) {
for func in &data.functions {
let params_str = func
.params
.iter()
.map(|p| format!("{}: {}", p.name, p.param_type))
.collect::<Vec<_>>()
.join(", ");
print!(" 函数: {}({})", func.name, params_str);
if let Some(ret) = &func.return_type {
print!(" -> {}", ret);
}
println!();
}
}
fn access_variables_constants(data: &MortaredData) {
println!(" 变量:");
for var in &data.variables {
print!(" let {}: {}", var.name, var.var_type);
if let Some(value) = &var.value {
print!(" = {:?}", value);
}
println!();
}
println!(" 常量:");
for constant in &data.constants {
print!(" ");
if constant.public {
print!("pub ");
}
println!(
"const {}: {} = {:?}",
constant.name, constant.const_type, constant.value
);
}
}
fn access_enums(data: &MortaredData) {
for enum_def in &data.enums {
println!(" 枚举 {} {{", enum_def.name);
for variant in &enum_def.variants {
println!(" {},", variant);
}
println!(" }}");
}
}
fn print_dialogue_events(item_value: &Value) {
let Some(events) = item_value.get("events").and_then(Value::as_array) else {
return;
};
for event in events {
let Some(actions) = event.get("actions").and_then(Value::as_array) else {
continue;
};
for action in actions {
let action_type = action.get("type").and_then(Value::as_str).unwrap_or("");
let args = action
.get("args")
.and_then(Value::as_array)
.cloned()
.unwrap_or_default();
println!(" [触发事件: {}({:?})]", action_type, args);
}
}
}
fn process_dialogue_item(item_value: &Value) -> bool {
let item_type = item_value.get("type").and_then(Value::as_str).unwrap_or("");
match item_type {
"text" => {
let text = item_value
.get("value")
.and_then(Value::as_str)
.unwrap_or("");
println!(" {}", text);
print_dialogue_events(item_value);
false
}
"choice" => {
if let Some(options) = item_value.get("options").and_then(Value::as_array) {
println!("\n 可用选项:");
for (i, choice) in options.iter().enumerate() {
let text = choice.get("text").and_then(Value::as_str).unwrap_or("");
println!(" {}. {}", i + 1, text);
}
println!(" (在实际游戏中,玩家会在这里做出选择)\n");
}
true
}
"run_event" => {
let name = item_value.get("name").and_then(Value::as_str).unwrap_or("");
println!(" [运行事件: {}]", name);
false
}
_ => false,
}
}
fn simulate_dialogue(data: &MortaredData) {
println!(" 开始模拟对话...\n");
let mut current_node_name = "Start";
loop {
let Some(node) = data.get_node(current_node_name) else {
println!(" 节点 '{}' 不存在!", current_node_name);
break;
};
println!(" === {} ===", node.name);
let end_simulation = node.content.iter().any(process_dialogue_item);
if end_simulation {
break;
}
if let Some(next) = &node.next {
current_node_name = next;
println!();
} else {
break;
}
}
}