use itertools::Itertools; use crate::data::RPC; pub const JSON_INNER_IMPLS: &[(&str, &str)] = &[ ("std::string", "String"), ("std::int8_t", "Int"), ("std::int16_t", "Int"), ("std::int32_t", "Int"), ("std::int64_t", "Int64"), ("std::uint8_t", "Uint"), ("std::uint16_t", "Uint"), ("std::uint32_t", "Uint"), ("std::uint64_t", "Uint64"), ("bool", "Bool"), ("std::float_t", "Double"), ("std::double_t", "Double") ]; pub fn ty_to_str(ty: &crate::data::Types) -> String { use crate::data::Types; match ty { Types::String => "std::string".into(), Types::Bool => "bool".into(), Types::F32 => "std::float_t".into(), Types::F64 => "std::double_t".into(), Types::I8 => "std::int8_t".into(), Types::I16 => "std::int16_t".into(), Types::I32 => "std::int32_t".into(), Types::I64 => "std::int64_t".into(), Types::U8 => "std::uint8_t".into(), Types::U16 => "std::uint16_t".into(), Types::U32 => "std::uint32_t".into(), Types::U64 => "std::uint64_t".into(), Types::Named(name) => name.into(), Types::Optional(inner) => format!("std::optional<{}>", ty_to_str(inner)), Types::Array(inner) => format!("std::vector<{}>", ty_to_str(inner)), Types::Generic(name, types) => format!("{}<{}>", name, types.iter().map(|ty| ty_to_str(ty)).join(", ")) } } pub fn get_struct_generics(s: &crate::data::StructTy) -> String { if s.generic_names.is_empty() { "".into() } else { format!("template<{}>\n", generics_brace_inner_typename(s)) } } pub fn generics_brace_inner_typename(s: &crate::data::StructTy) -> String { s.generic_names.iter().map(|n| String::from("typename ") + n).join(", ") } pub fn generics_brace(s: &crate::data::StructTy) -> String { if s.generic_names.is_empty() { "".into() } else { format!("<{}>", generics_brace_inner(s)) } } pub fn generics_brace_inner(s: &crate::data::StructTy) -> String { s.generic_names.iter().join(", ") } pub fn method_args(method: &crate::data::MethodTy) -> String { method.args.iter() .map(|arg| format!("{} &&{}", ty_to_str(&arg.ty), arg.name)) .chain(method.ret_stream.then(|| format!("MRPCStream<{}>&&", ty_to_str(method.ret.as_ref().unwrap())))) .join(", ") } pub fn method_ret(method: &crate::data::MethodTy) -> String { if method.ret_stream || method.ret.is_none() { "void".into() } else { ty_to_str(method.ret.as_ref().unwrap()) } } pub fn call_args(method: &crate::data::MethodTy) -> String { method.args.iter() .map(|arg| format!("std::move({})", arg.name)) .chain(method.ret_stream.then_some(String::from("std::move(__stream)"))) .join(", ") } pub fn streams_required(rpc: &RPC) -> Vec { let mut streams = std::collections::HashSet::new(); for s in &rpc.services { for m in &s.methods { if m.ret_stream { streams.insert(ty_to_str(m.ret.as_ref().unwrap())); } } } streams.into_iter().collect() } pub fn gen(file_base_name: &std::path::PathBuf, rpc: &RPC) { let header_name = file_base_name.with_extension("hxx"); let h = std::fs::File::create(&header_name).unwrap(); let header_name = header_name.file_name().unwrap().to_str().unwrap(); let c = std::fs::File::create(file_base_name.with_extension("cxx")).unwrap(); crate::templates::cpp_server_hxx(h, rpc).unwrap(); crate::templates::cpp_server_cxx(c, header_name, rpc).unwrap(); }