serde_yaml_risp/
lib.rs

1use risp::types::RispType;
2use serde_yaml::Value;
3
4pub fn convert(yaml_term: &Value) -> RispType {
5    match yaml_term {
6        Value::Null => RispType::Nil,
7        Value::String(var) => RispType::Symbol(var.to_string()),
8        Value::Bool(var) => RispType::Bool(*var),
9        Value::Number(var) => RispType::Int(var.as_i64().unwrap()),
10        // TODO mappings could be used to apply functions
11        Value::Mapping(_) => RispType::Str("TODO mappings".to_string()),
12        Value::Sequence(vec) => match vec.as_slice() {
13            [] => RispType::Str("TODO empty sequence".to_string()),
14            [Value::String(ref def), Value::String(name), val] if def == "def" => {
15                RispType::List(vec![
16                    RispType::Symbol(def.to_string()),
17                    RispType::Symbol(name.to_string()),
18                    convert(val),
19                ])
20            }
21            [Value::String(ref defn), Value::String(name), Value::Sequence(params), val @ Value::Sequence(_)]
22                if defn == "defn" =>
23            {
24                RispType::List(vec![
25                    RispType::Symbol(defn.to_string()),
26                    RispType::Symbol(name.to_string()),
27                    RispType::Vector(params.iter().map(|term| convert(term)).collect()),
28                    convert(val),
29                ])
30            }
31            // here we take on rust's syntax to distinguish lists and vectors
32            [Value::String(ref term0), terms @ ..] if term0 == "vec!" => {
33                RispType::Vector(terms.iter().map(|term| convert(term)).collect())
34            }
35            terms => RispType::List(terms.iter().map(|term| convert(term)).collect()),
36        },
37    }
38}