diff --git a/src/config/fixargs.rs b/src/config/fixargs.rs deleted file mode 100644 index 0a8bfb4..0000000 --- a/src/config/fixargs.rs +++ /dev/null @@ -1,145 +0,0 @@ -use base64::Engine; -use tailcall_valid::{Valid, Validator}; -use crate::config::config::{Config, Field, Interface, Record}; -use crate::config::wit_types::WitType; -use crate::merge_right::MergeRight; -use crate::tryfold::TryFold; - -pub fn fix_args(config: Config) -> Valid { - Valid::succeed(config) - .and_then(|mut config| { - Valid::from_iter(config.interfaces.iter().cloned().collect::>(), |mut interface| { - Valid::from_iter(interface.records.iter().cloned(), |mut record| { - Valid::from_iter(record.fields.iter().cloned(), |field| { - if !field.field_type.is_kind_of_primitive() { - fix_field() - .try_fold(&(&config, &interface, &record, &field, &field.field_type), Field::default()) - .and_then(|field| { - Valid::succeed(Some(field)) - }) - }else { - Valid::succeed(None) - } - }).and_then(|v| { - let fields = v.into_iter().filter_map(|x| x).collect(); - record.added_fields = fields; - - Valid::succeed(record) - }) - }).and_then(|records| { - interface.records = records.into_iter().collect(); - Valid::succeed(interface) - }) - }).and_then(|interfaces| { - config.interfaces = interfaces.into_iter().collect(); - /*for interface in interfaces { - if let Some(interface) = config.interfaces.iter().find(|i| i.name == interface.name) { - for record in interface.records { - if let Some(mut record) = interface.records.iter().find(|r| r.name == record.name).cloned() { - for field in record.fields { - if let Some(field) = record.fields.iter().find(|f| f.name == field.name) { - let mut new_field = field.clone(); - new_field.field_type = field.field_type.clone().merge_right(new_field.field_type.clone()); - record.fields.remove(&field); - record.fields.insert(new_field); - } - } - } - } - }else { - config.interfaces.insert(interface); - } - }*/ -/* let mut new_interfaces = BTreeSet::new(); - for mut interface in config.interfaces { - let mut new_records = BTreeSet::new(); - for mut record in interface.records { - let mut new_fields = BTreeSet::new(); - for mut field in record.fields { - let mut new_field = interfaces - .iter() - .find(|i| i.name == interface.name).and_then(|interface| interface.records.iter().find(|r| r.name == record.name).and_then(|record|record.fields.iter().find(|f| f.name == field.name))) - .unwrap_or(&field) - .clone(); - - new_field = new_field.merge_right(field); - new_fields.insert(new_field); - } - record.fields = new_fields; - new_records.insert(record); - } - interface.records = new_records; - new_interfaces.insert(interface); - } - - config.interfaces = new_interfaces;*/ - // config.interfaces = config.interfaces.merge_right(map); - - Valid::succeed(config) - }) - }) -} - -/* -interface types { - - record error { error: { message: string, details: list<{ field: string, message: string }>, code: string } } - record todo { completed: bool, created-at: string, description: string, due-date: string, id: string, title: string, updated-at: string, user-id: string } - record todo-create { description: string, due-date: string, title: string, user-id: string } - record todo-list { data: list<{ id: string, user-id: string, title: string, due-date: string, created-at: string, updated-at: string, completed: bool, description: string }>, metadata: { total: s32, offset: s32, limit: s32 } } - record todo-response { data: { id: string, user-id: string, title: string, due-date: string, created-at: string, updated-at: string, completed: bool, description: string } } - record todo-update { completed: bool, description: string, due-date: string, title: string } - -} -*/ - -fn fix_field<'a>() -> TryFold<'a, (&'a Config, &'a Interface, &'a Record, &'a Field, &'a WitType), Field, anyhow::Error> { - TryFold::<(&Config, &Interface, &Record, &Field, &WitType), Field, anyhow::Error>::new(move |(config, interface, rec, field, wit), o| { - match &wit { - WitType::Option(x) => { - return fix_field().try_fold(&(*config, *interface, *rec, *field, x), o); - } - WitType::Result(a, b) => { - // TODO: this impl needs check. - // eg: -> result - // this does not make sense to resolve with rec.name-A/B - - return if !a.is_primitive() { - fix_field().try_fold(&(*config, *interface, *rec, *field, a), o) - } else if !b.is_primitive() { - fix_field().try_fold(&(*config, *interface, *rec, *field, b), o) - } else { - // TODO: Fix the possible conflicts here - fix_field().try_fold(&(*config, *interface, *rec, *field, a), o) - .and_then(|new_interface| fix_field().try_fold(&(*config, *interface, *rec, *field, b), new_interface)) - }; - } - WitType::List(x) => fix_field().try_fold(&(*config, *interface, *rec, *field, x.as_ref()), o), - WitType::Tuple(x) => { - // TODO: Fix the possible conflicts here - return Valid::from_iter(x.iter(), |x| fix_field().try_fold(&(*config, *interface, *rec, *field, x), o.clone())) - .and_then(|v| Valid::succeed(v.into_iter().fold((*field).clone(), |a, b| { - a.merge_right(b) - }))); - } - WitType::Record(records) => { - let field_name = if field.name.is_empty() { - base64::prelude::BASE64_STANDARD.encode(field.name.as_bytes()) - } else { - field.name.clone() - }; - let name = format!("{}-{}", rec.name, field_name); - - let new_field = Field { - name, - field_type: WitType::Record(records.clone()), - }; - Valid::succeed(new_field) - } - WitType::FieldTy(_) => Valid::succeed(o), - // Ideally this case should never happen, - // but we should always throw an error to avoid infinite recursion - _ => return Valid::fail(anyhow::anyhow!("Unknown type: {:?}", field.field_type)), - } - }) -} diff --git a/src/config/mod.rs b/src/config/mod.rs index 193fee1..2ac85cd 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,5 +1,3 @@ pub mod config; pub mod wit_types; pub mod to_wit; -pub mod fixargs; -pub mod handle_files; diff --git a/src/config/wit_types.rs b/src/config/wit_types.rs index b60c0bb..b755f3e 100644 --- a/src/config/wit_types.rs +++ b/src/config/wit_types.rs @@ -40,26 +40,6 @@ pub enum WitType { } impl WitType { - pub fn is_primitive(&self) -> bool { - match self { - WitType::Bool | WitType::U8 | WitType::U16 | WitType::U32 | WitType::U64 | WitType::S8 | WitType::S16 | WitType::S32 | WitType::S64 | WitType::Float32 | WitType::Float64 | WitType::Char | WitType::String => true, - _ => false, - } - } - pub fn is_kind_of_primitive(&self) -> bool { - match self { - WitType::Option(x) => x.is_primitive(), - WitType::Result(a, b) => a.is_primitive() && b.is_primitive(), - WitType::List(x) => x.is_primitive(), - WitType::Tuple(x) => x.iter().all(|x| x.is_primitive()), - WitType::Variant(_) => true, - WitType::Enum(_) => true, - WitType::Flags(_) => true, - WitType::Handle(_) => true, - WitType::TypeAlias(_, _) => true, - v => v.is_primitive(), - } - } pub fn from_schema( schema: &Schema, openapi: &OpenApiSpec, diff --git a/src/main.rs b/src/main.rs index 53a1d55..b700ecc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,7 @@ mod transform; mod tryfold; mod merge_right; mod primitive; +mod proto; #[derive(Debug, Clone)] pub struct WIPValue(Value); diff --git a/src/config/handle_files.rs b/src/openapi/handle_files.rs similarity index 100% rename from src/config/handle_files.rs rename to src/openapi/handle_files.rs diff --git a/src/openapi/mod.rs b/src/openapi/mod.rs index 241f8ed..552e11e 100644 --- a/src/openapi/mod.rs +++ b/src/openapi/mod.rs @@ -1,2 +1,3 @@ pub mod openapi_spec; -pub mod openapi; \ No newline at end of file +pub mod openapi; +pub(super) mod handle_files; diff --git a/src/openapi/openapi_spec.rs b/src/openapi/openapi_spec.rs index b1a12c1..f65d4fa 100644 --- a/src/openapi/openapi_spec.rs +++ b/src/openapi/openapi_spec.rs @@ -4,9 +4,8 @@ use anyhow::Error; use convert_case::{Case, Casing}; use schemars::JsonSchema; use tailcall_valid::{Valid, Validator}; -use crate::config::fixargs::fix_args; -use crate::config::handle_files::handle_types; use crate::config::config::Config; +use crate::openapi::handle_files::handle_types; #[derive(Default)] pub struct Unresolved; @@ -250,7 +249,6 @@ impl OpenApiSpec { pub fn to_config(&self) -> Valid { Valid::succeed(Config::default()) .and_then(|config| handle_types(config, &self)) - .and_then(|config| fix_args(config)) } } diff --git a/src/proto/handle_types.rs b/src/proto/handle_types.rs new file mode 100644 index 0000000..1dfae4a --- /dev/null +++ b/src/proto/handle_types.rs @@ -0,0 +1,45 @@ +use std::collections::BTreeSet; +use oas3::spec::ParameterIn::Path; +use protox::prost_reflect::prost_types::{field_descriptor_proto, FileDescriptorProto, FileDescriptorSet}; +use tailcall_valid::{Valid, Validator}; +use crate::config::config::{Config, Field, Interface, Record}; +use crate::config::wit_types::WitType; + +fn append_enums(config: &Config, file: &FileDescriptorProto) -> Valid { + todo!() +} + +fn append_message(config: &Config, file: &FileDescriptorProto) -> Valid { + todo!() +} + +pub fn handle_types(config: Config, proto: &[FileDescriptorSet], package: String) -> Valid { + Valid::succeed(config) + .and_then(|config| { + Valid::from_iter(proto.iter(), |set| { + Valid::from_iter(set.file.iter(), |file| { + append_enums(&config, file).and_then(|rec| { + append_message(&config, file) + .and_then(|mut new_rec| { + new_rec.fields.extend(rec.fields); + Valid::succeed(new_rec) + }) + }) + }) + .and_then(|v| { + Valid::succeed(Interface { + name: "type".to_string(), + records: v.into_iter().collect(), + uses: vec![], + functions: vec![], + }) + }) + }) + }).and_then(|v| { + Valid::succeed(Config { + package, + interfaces: v.into_iter().collect(), + world: Default::default(), + }) + }) +} diff --git a/src/proto/mod.rs b/src/proto/mod.rs new file mode 100644 index 0000000..a1f1612 --- /dev/null +++ b/src/proto/mod.rs @@ -0,0 +1,2 @@ +mod proto; +mod handle_types; \ No newline at end of file diff --git a/src/proto/proto.rs b/src/proto/proto.rs new file mode 100644 index 0000000..5227a1b --- /dev/null +++ b/src/proto/proto.rs @@ -0,0 +1,16 @@ +use protox::prost_reflect::prost_types::FileDescriptorSet; +use tailcall_valid::{Valid, Validator}; +use crate::config::config::Config; +use crate::proto::handle_types::handle_types; + +pub struct Proto(Vec); + +impl Proto { + pub fn new>(v: T) -> Self { + Self(v.into_iter().collect()) + } + pub fn to_config(&self) -> Valid { + Valid::succeed(Config::default()) + .and_then(|config| handle_types(config, &self.0)) + } +} \ No newline at end of file