use crate::spec::{Field, MessageSpecification};
use minijinja::{value::Value, Environment};
use std::collections::HashMap;
pub fn prepare_environment<'a>(
message_template: &'a str,
service_template: &'a str,
typename_conversion_mapping: Option<HashMap<String, String>>,
) -> Environment<'a> {
let mut env = Environment::new();
env.add_function("has_header", has_header);
env.add_function("is_fixed_length", is_fixed_length);
env.add_function("is_intrinsic_type", is_intrinsic_type);
env.add_function("is_vector", is_vector_type);
env.add_function("is_fixed_array", is_fixed_size_array_type);
env.add_filter("fixed_size_array_size", fixed_size_array_size);
if let Some(map) = typename_conversion_mapping {
env.add_filter("typename_conversion", move |v: Value| {
let value = serde_json::to_value(v).unwrap();
let ros_type = value.as_str().unwrap();
let typename = match map.get(ros_type) {
Some(native_type) => native_type.clone(),
None => ros_type.to_string(),
};
Value::from_serialize(&typename)
});
}
env.add_template("message", message_template).unwrap();
env.add_template("service", service_template).unwrap();
env
}
pub fn has_header(value: Value) -> bool {
if let Ok(value) = serde_json::to_value(value) {
if let Ok(spec) = serde_json::from_value::<MessageSpecification>(value) {
spec.fields
.iter()
.any(|field| field.field_type.as_str() == "Header")
} else {
false
}
} else {
false
}
}
pub fn is_fixed_length(value: Value) -> bool {
if let Ok(value) = serde_json::to_value(value) {
if let Ok(spec) = serde_json::from_value::<MessageSpecification>(value) {
spec.is_fixed_length
} else {
false
}
} else {
false
}
}
pub fn is_intrinsic_type(value: Value) -> bool {
if let Ok(value) = serde_json::to_value(value) {
if let Ok(field) = serde_json::from_value::<Field>(value) {
field.is_intrinsic_type()
} else {
false
}
} else {
false
}
}
pub fn is_vector_type(value: Value) -> bool {
if let Ok(v) = serde_json::to_value(value.clone()) {
if let Ok(field) = serde_json::from_value::<Field>(v) {
field.is_vector_type()
} else {
false
}
} else {
false
}
}
pub fn is_fixed_size_array_type(value: Value) -> bool {
if let Ok(value) = serde_json::to_value(value) {
if let Ok(field) = serde_json::from_value::<Field>(value) {
field.is_fixed_size_array_type()
} else {
false
}
} else {
false
}
}
pub fn fixed_size_array_size(value: Value) -> Value {
let fixed_size = if let Ok(value) = serde_json::to_value(value) {
if let Ok(field) = serde_json::from_value::<Field>(value) {
field.fixed_size_array_size()
} else {
0
}
} else {
0
};
Value::from_serialize(fixed_size)
}