cleanup code

This commit is contained in:
Sandipsinh Rathod 2024-12-22 20:47:24 -05:00
parent 711973e03e
commit 93e8ff903c
13 changed files with 40 additions and 601 deletions

10
Cargo.lock generated

@ -186,7 +186,6 @@ dependencies = [
"convert_case", "convert_case",
"derive_setters", "derive_setters",
"lazy_static", "lazy_static",
"macros",
"oapi", "oapi",
"oas3", "oas3",
"openapi3-parser", "openapi3-parser",
@ -523,15 +522,6 @@ dependencies = [
"logos-codegen", "logos-codegen",
] ]
[[package]]
name = "macros"
version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.90",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.7.4" version = "2.7.4"

@ -21,8 +21,7 @@ wit-parser = "0.222.0"
lazy_static = "1.5.0" lazy_static = "1.5.0"
base64 = "0.22.1" base64 = "0.22.1"
strum_macros = "0.26.4" strum_macros = "0.26.4"
macros = {path = "macros"}
derive_setters = "0.1.6" derive_setters = "0.1.6"
[workspace] [workspace]
members = [".", "macros"] members = ["."]

7
macros/Cargo.lock generated

@ -1,7 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "macros"
version = "0.1.0"

@ -1,12 +0,0 @@
[package]
name = "macros"
version = "0.1.0"
edition = "2021"
[lib]
proc-macro = true
[dependencies]
syn = { version = "2.0.60", features = ["derive", "full"] }
quote = "1.0.36"
proc-macro2 = "1.0.81"

@ -1,9 +0,0 @@
use proc_macro::TokenStream;
mod merge_right;
use crate::merge_right::expand_merge_right_derive;
#[proc_macro_derive(MergeRight, attributes(merge_right))]
pub fn merge_right_derive(input: TokenStream) -> TokenStream {
expand_merge_right_derive(input)
}

@ -1,186 +0,0 @@
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn::spanned::Spanned;
use syn::{parse_macro_input, Data, DeriveInput, Fields, Index};
const MERGE_RIGHT_FN: &str = "merge_right_fn";
const MERGE_RIGHT: &str = "merge_right";
#[derive(Default)]
struct Attrs {
merge_right_fn: Option<syn::ExprPath>,
}
fn get_attrs(attrs: &[syn::Attribute]) -> syn::Result<Attrs> {
let mut attrs_ret = Attrs::default();
for attr in attrs {
if attr.path().is_ident(MERGE_RIGHT) {
attr.parse_nested_meta(|meta| {
if meta.path.is_ident(MERGE_RIGHT_FN) {
let p: syn::Expr = meta.value()?.parse()?;
let lit =
if let syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Str(lit), .. }) = p {
let suffix = lit.suffix();
if !suffix.is_empty() {
return Err(syn::Error::new(
lit.span(),
format!("unexpected suffix `{}` on string literal", suffix),
));
}
lit
} else {
return Err(syn::Error::new(
p.span(),
format!(
"expected merge_right {} attribute to be a string.",
MERGE_RIGHT_FN
),
));
};
let expr_path: syn::ExprPath = lit.parse()?;
attrs_ret.merge_right_fn = Some(expr_path);
Ok(())
} else {
Err(syn::Error::new(attr.span(), "Unknown helper attribute."))
}
})?;
}
}
Ok(attrs_ret)
}
pub fn expand_merge_right_derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let name = input.ident.clone();
let generics = input.generics.clone();
let gen = match input.data {
// Implement for structs
Data::Struct(data) => {
let fields = match &data.fields {
Fields::Named(fields) => &fields.named,
Fields::Unnamed(fields) => &fields.unnamed,
Fields::Unit => {
return quote! {
impl crate::merge_right::MergeRight for #name {
fn merge_right(self, other: Self) -> Self {
other
}
}
}
.into()
}
};
let merge_logic = fields.iter().enumerate().map(|(i, f)| {
let attrs = get_attrs(&f.attrs);
if let Err(err) = attrs {
panic!("{}", err);
}
let attrs = attrs.unwrap();
let name = &f.ident;
match &data.fields {
Fields::Named(_) => {
if let Some(merge_right_fn) = attrs.merge_right_fn {
quote! {
#name: #merge_right_fn(self.#name, other.#name),
}
} else {
quote! {
#name: self.#name.merge_right(other.#name),
}
}
}
Fields::Unnamed(_) => {
let name = Index::from(i);
if let Some(merge_right_fn) = attrs.merge_right_fn {
quote! {
#merge_right_fn(self.#name, other.#name),
}
} else {
quote! {
self.#name.merge_right(other.#name),
}
}
}
Fields::Unit => unreachable!(),
}
});
let generics_lt = generics.lt_token;
let generics_gt = generics.gt_token;
let generics_params = generics.params;
let generics_del = quote! {
#generics_lt #generics_params #generics_gt
};
let initializer = match data.fields {
Fields::Named(_) => quote! {
Self {
#(#merge_logic)*
}
},
Fields::Unnamed(_) => quote! {
Self(#(#merge_logic)*)
},
Fields::Unit => unreachable!(),
};
quote! {
impl #generics_del crate::merge_right::MergeRight for #name #generics_del {
fn merge_right(self, other: Self) -> Self {
#initializer
}
}
}
}
// Implement for enums
Data::Enum(_) => quote! {
impl crate::merge_right::MergeRight for #name {
fn merge_right(self, other: Self) -> Self {
other
}
}
},
// Optionally handle or disallow unions
Data::Union(_) => {
return syn::Error::new_spanned(input, "Union types are not supported by MergeRight")
.to_compile_error()
.into()
}
};
gen.into()
}
#[cfg(test)]
mod tests {
use syn::{parse_quote, Attribute};
use super::*;
#[test]
fn test_get_attrs_invalid_type() {
let attrs: Vec<Attribute> = vec![parse_quote!(#[merge_right(merge_right_fn = 123)])];
let result = get_attrs(&attrs);
assert!(
result.is_err(),
"Expected error with non-string type for `merge_right_fn`"
);
}
#[test]
fn test_get_attrs_unexpected_suffix() {
let attrs: Vec<Attribute> =
vec![parse_quote!(#[merge_right(merge_right_fn = "some_fn()")])];
let result = get_attrs(&attrs);
assert!(
result.is_err(),
"Expected error with unexpected suffix on string literal"
);
}
}

@ -1,16 +1,15 @@
use std::collections::{BTreeMap, BTreeSet}; use std::collections::{BTreeMap, BTreeSet};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use macros::MergeRight;
use crate::config::wit_types::WitType; use crate::config::wit_types::WitType;
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight)] #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Config { pub struct Config {
pub package: String, pub package: String,
pub interfaces: BTreeSet<Interface>, pub interfaces: BTreeSet<Interface>,
pub world: World, pub world: World,
} }
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight)] #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct World { pub struct World {
pub name: String, pub name: String,
pub uses: Vec<UseStatement>, pub uses: Vec<UseStatement>,
@ -18,7 +17,7 @@ pub struct World {
pub exports: Vec<Interface>, pub exports: Vec<Interface>,
} }
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight, derive_setters::Setters)] #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, derive_setters::Setters)]
pub struct Interface { pub struct Interface {
pub name: String, pub name: String,
pub varients: BTreeMap<String, WitType>, pub varients: BTreeMap<String, WitType>,
@ -39,7 +38,7 @@ impl Ord for Interface {
} }
} }
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight)] #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Record { pub struct Record {
pub name: String, pub name: String,
pub fields: BTreeSet<Field>, pub fields: BTreeSet<Field>,
@ -58,32 +57,32 @@ impl Ord for Record {
} }
} }
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight)] #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct UseStatement { pub struct UseStatement {
pub name: String, pub name: String,
pub items: Vec<String>, pub items: Vec<String>,
} }
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight)] #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Function { pub struct Function {
pub name: String, pub name: String,
pub parameters: Vec<Parameter>, pub parameters: Vec<Parameter>,
pub return_type: ReturnTy, pub return_type: ReturnTy,
} }
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight)] #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct ReturnTy { pub struct ReturnTy {
pub return_type: String, pub return_type: String,
pub error_type: Option<String>, pub error_type: Option<String>,
} }
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight)] #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Parameter { pub struct Parameter {
pub name: String, pub name: String,
pub parameter_type: String, pub parameter_type: String,
} }
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight)] #[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Field { pub struct Field {
pub name: String, pub name: String,
pub field_type: WitType, pub field_type: WitType,

@ -7,11 +7,8 @@ use crate::value::value;
mod value; mod value;
mod openapi; mod openapi;
mod config; mod config;
mod transformer;
mod transform; mod transform;
mod tryfold; mod tryfold;
mod merge_right;
mod primitive;
mod proto; mod proto;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]

@ -1,292 +0,0 @@
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use crate::config::wit_types::WitType;
pub trait MergeRight {
fn merge_right(self, other: Self) -> Self;
}
impl<A: MergeRight> MergeRight for Option<A> {
fn merge_right(self, other: Self) -> Self {
match (self, other) {
(Some(this), Some(that)) => Some(this.merge_right(that)),
(None, Some(that)) => Some(that),
(Some(this), None) => Some(this),
(None, None) => None,
}
}
}
impl<A> MergeRight for Vec<A> {
fn merge_right(mut self, other: Self) -> Self {
self.extend(other);
self
}
}
impl<V> MergeRight for BTreeSet<V>
where
V: Ord + MergeRight,
{
fn merge_right(self, mut other: Self) -> Self {
other.extend(self);
other
}
}
impl<V> MergeRight for HashSet<V>
where
V: Eq + std::hash::Hash,
{
fn merge_right(mut self, other: Self) -> Self {
self.extend(other);
self
}
}
impl<K, V> MergeRight for BTreeMap<K, V>
where
K: Ord,
V: MergeRight,
{
fn merge_right(mut self, other: Self) -> Self {
for (other_name, mut other_value) in other {
if let Some(self_value) = self.remove(&other_name) {
other_value = self_value.merge_right(other_value);
}
self.insert(other_name, other_value);
}
self
}
}
impl<K, V> MergeRight for HashMap<K, V>
where
K: Eq + std::hash::Hash,
V: MergeRight,
{
fn merge_right(mut self, other: Self) -> Self {
for (other_name, mut other_value) in other {
if let Some(self_value) = self.remove(&other_name) {
other_value = self_value.merge_right(other_value);
}
self.insert(other_name, other_value);
}
self
}
}
impl MergeRight for WitType {
fn merge_right(self, other: Self) -> Self {
other
}
}
#[cfg(test)]
mod tests {
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use super::MergeRight;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
struct Test(u32);
impl From<u32> for Test {
fn from(value: u32) -> Self {
Self(value)
}
}
impl MergeRight for Test {
fn merge_right(self, other: Self) -> Self {
Self(self.0 + other.0)
}
}
#[test]
fn test_option() {
let x: Option<Test> = None.merge_right(None);
assert_eq!(x, None);
let x = Some(Test::from(1)).merge_right(None);
assert_eq!(x, Some(Test::from(1)));
let x = None.merge_right(Some(Test::from(2)));
assert_eq!(x, Some(Test::from(2)));
let x = Some(Test::from(1)).merge_right(Some(Test::from(2)));
assert_eq!(x, Some(Test::from(3)));
}
#[test]
fn test_vec() {
let l: Vec<Test> = vec![];
let r: Vec<Test> = vec![];
assert_eq!(l.merge_right(r), vec![]);
let l: Vec<Test> = vec![Test::from(1), Test::from(2)];
let r: Vec<Test> = vec![];
assert_eq!(l.merge_right(r), vec![Test::from(1), Test::from(2)]);
let l: Vec<Test> = vec![];
let r: Vec<Test> = vec![Test::from(3), Test::from(4)];
assert_eq!(l.merge_right(r), vec![Test::from(3), Test::from(4)]);
let l: Vec<Test> = vec![Test::from(1), Test::from(2)];
let r: Vec<Test> = vec![Test::from(3), Test::from(4)];
assert_eq!(
l.merge_right(r),
vec![Test::from(1), Test::from(2), Test::from(3), Test::from(4)]
);
}
#[test]
fn test_btree_set() {
let l: BTreeSet<Test> = BTreeSet::from_iter(vec![]);
let r: BTreeSet<Test> = BTreeSet::from_iter(vec![]);
assert_eq!(l.merge_right(r), BTreeSet::from_iter(vec![]));
let l: BTreeSet<Test> = BTreeSet::from_iter(vec![Test::from(1), Test::from(2)]);
let r: BTreeSet<Test> = BTreeSet::from_iter(vec![]);
assert_eq!(
l.merge_right(r),
BTreeSet::from_iter(vec![Test::from(1), Test::from(2)])
);
let l: BTreeSet<Test> = BTreeSet::from_iter(vec![]);
let r: BTreeSet<Test> = BTreeSet::from_iter(vec![Test::from(3), Test::from(4)]);
assert_eq!(
l.merge_right(r),
BTreeSet::from_iter(vec![Test::from(3), Test::from(4)])
);
let l: BTreeSet<Test> = BTreeSet::from_iter(vec![Test::from(1), Test::from(2)]);
let r: BTreeSet<Test> =
BTreeSet::from_iter(vec![Test::from(2), Test::from(3), Test::from(4)]);
assert_eq!(
l.merge_right(r),
BTreeSet::from_iter(vec![
Test::from(1),
Test::from(2),
Test::from(3),
Test::from(4)
])
);
}
#[test]
fn test_hash_set() {
let l: HashSet<Test> = HashSet::from_iter(vec![]);
let r: HashSet<Test> = HashSet::from_iter(vec![]);
assert_eq!(l.merge_right(r), HashSet::from_iter(vec![]));
let l: HashSet<Test> = HashSet::from_iter(vec![Test::from(1), Test::from(2)]);
let r: HashSet<Test> = HashSet::from_iter(vec![]);
assert_eq!(
l.merge_right(r),
HashSet::from_iter(vec![Test::from(1), Test::from(2)])
);
let l: HashSet<Test> = HashSet::from_iter(vec![]);
let r: HashSet<Test> = HashSet::from_iter(vec![Test::from(3), Test::from(4)]);
assert_eq!(
l.merge_right(r),
HashSet::from_iter(vec![Test::from(3), Test::from(4)])
);
let l: HashSet<Test> = HashSet::from_iter(vec![Test::from(1), Test::from(2)]);
let r: HashSet<Test> =
HashSet::from_iter(vec![Test::from(2), Test::from(3), Test::from(4)]);
assert_eq!(
l.merge_right(r),
HashSet::from_iter(vec![
Test::from(1),
Test::from(2),
Test::from(3),
Test::from(4)
])
);
}
#[test]
fn test_btree_map() {
let l: BTreeMap<u32, Test> = BTreeMap::from_iter(vec![]);
let r: BTreeMap<u32, Test> = BTreeMap::from_iter(vec![]);
assert_eq!(l.merge_right(r), BTreeMap::from_iter(vec![]));
let l: BTreeMap<u32, Test> =
BTreeMap::from_iter(vec![(1, Test::from(1)), (2, Test::from(2))]);
let r: BTreeMap<u32, Test> = BTreeMap::from_iter(vec![]);
assert_eq!(
l.merge_right(r),
BTreeMap::from_iter(vec![(1, Test::from(1)), (2, Test::from(2))])
);
let l: BTreeMap<u32, Test> = BTreeMap::from_iter(vec![]);
let r: BTreeMap<u32, Test> =
BTreeMap::from_iter(vec![(3, Test::from(3)), (4, Test::from(4))]);
assert_eq!(
l.merge_right(r),
BTreeMap::from_iter(vec![(3, Test::from(3)), (4, Test::from(4))])
);
let l: BTreeMap<u32, Test> =
BTreeMap::from_iter(vec![(1, Test::from(1)), (2, Test::from(2))]);
let r: BTreeMap<u32, Test> = BTreeMap::from_iter(vec![
(2, Test::from(5)),
(3, Test::from(3)),
(4, Test::from(4)),
]);
assert_eq!(
l.merge_right(r),
BTreeMap::from_iter(vec![
(1, Test::from(1)),
(2, Test::from(7)),
(3, Test::from(3)),
(4, Test::from(4))
])
);
}
#[test]
fn test_hash_map() {
let l: HashMap<u32, Test> = HashMap::from_iter(vec![]);
let r: HashMap<u32, Test> = HashMap::from_iter(vec![]);
assert_eq!(l.merge_right(r), HashMap::from_iter(vec![]));
let l: HashMap<u32, Test> =
HashMap::from_iter(vec![(1, Test::from(1)), (2, Test::from(2))]);
let r: HashMap<u32, Test> = HashMap::from_iter(vec![]);
assert_eq!(
l.merge_right(r),
HashMap::from_iter(vec![(1, Test::from(1)), (2, Test::from(2))])
);
let l: HashMap<u32, Test> = HashMap::from_iter(vec![]);
let r: HashMap<u32, Test> =
HashMap::from_iter(vec![(3, Test::from(3)), (4, Test::from(4))]);
assert_eq!(
l.merge_right(r),
HashMap::from_iter(vec![(3, Test::from(3)), (4, Test::from(4))])
);
let l: HashMap<u32, Test> =
HashMap::from_iter(vec![(1, Test::from(1)), (2, Test::from(2))]);
let r: HashMap<u32, Test> = HashMap::from_iter(vec![
(2, Test::from(5)),
(3, Test::from(3)),
(4, Test::from(4)),
]);
assert_eq!(
l.merge_right(r),
HashMap::from_iter(vec![
(1, Test::from(1)),
(2, Test::from(7)),
(3, Test::from(3)),
(4, Test::from(4))
])
);
}
}

@ -1,29 +0,0 @@
use std::marker::PhantomData;
use std::num::NonZeroU64;
use crate::merge_right::MergeRight;
pub trait Primitive {}
impl Primitive for bool {}
impl Primitive for char {}
impl Primitive for f32 {}
impl Primitive for f64 {}
impl Primitive for i16 {}
impl Primitive for i32 {}
impl Primitive for i64 {}
impl Primitive for i8 {}
impl Primitive for NonZeroU64 {}
impl Primitive for String {}
impl Primitive for u16 {}
impl Primitive for u32 {}
impl Primitive for u64 {}
impl Primitive for u8 {}
impl Primitive for usize {}
impl<A> Primitive for PhantomData<A> {}
impl<A: Primitive> MergeRight for A {
fn merge_right(self, other: Self) -> Self {
other
}
}

@ -1,19 +1,18 @@
use std::collections::{BTreeMap, BTreeSet}; use std::collections::{BTreeMap, BTreeSet};
use anyhow::anyhow;
use convert_case::Case;
use protox::prost_reflect::prost_types::{DescriptorProto, EnumDescriptorProto, FileDescriptorProto, FileDescriptorSet}; use convert_case::Case;
use convert_case::Casing;
use protox::prost_reflect::prost_types::{DescriptorProto, EnumDescriptorProto, FileDescriptorSet};
use tailcall_valid::{Valid, Validator}; use tailcall_valid::{Valid, Validator};
use crate::config::config::{Config, Field, Interface, Record}; use crate::config::config::{Config, Field, Interface, Record};
use crate::config::wit_types::WitType; use crate::config::wit_types::WitType;
use convert_case::Casing;
use crate::proto::proto::process_ty; use crate::proto::proto::process_ty;
fn append_enums(file: &[EnumDescriptorProto]) -> Valid<BTreeMap<String, WitType>, anyhow::Error, anyhow::Error> { fn append_enums(file: &[EnumDescriptorProto]) -> Valid<BTreeMap<String, WitType>, anyhow::Error, anyhow::Error> {
Valid::from_iter(file.iter().enumerate(), |(i, enum_)| { Valid::from_iter(file.iter(), |enum_| {
let enum_name = enum_.name().to_case(Case::Kebab); let enum_name = enum_.name().to_case(Case::Kebab);
Valid::from_iter(enum_.value.iter().enumerate(), |(j, value)| { Valid::from_iter(enum_.value.iter(), |value| {
Valid::succeed(value.name().to_case(Case::Kebab)) Valid::succeed(value.name().to_case(Case::Kebab))
}).and_then(|varients| { }).and_then(|varients| {
Valid::succeed((enum_name, WitType::Enum(varients))) Valid::succeed((enum_name, WitType::Enum(varients)))
@ -24,7 +23,7 @@ fn append_enums(file: &[EnumDescriptorProto]) -> Valid<BTreeMap<String, WitType>
fn append_message(messages: &[DescriptorProto]) -> Valid<Vec<Record>, anyhow::Error, anyhow::Error> { fn append_message(messages: &[DescriptorProto]) -> Valid<Vec<Record>, anyhow::Error, anyhow::Error> {
Valid::from_iter(messages.iter(), |message| { Valid::from_iter(messages.iter(), |message| {
let record_name = message.name().to_case(Case::Kebab); let record_name = message.name().to_case(Case::Kebab);
Valid::from_iter(message.field.iter().enumerate(), |(i, field)| { Valid::from_iter(message.field.iter(), |field| {
if let Some(ty_) = field.type_name.as_ref() { if let Some(ty_) = field.type_name.as_ref() {
process_ty(ty_).map(|ty| (field.name().to_case(Case::Kebab), ty)) process_ty(ty_).map(|ty| (field.name().to_case(Case::Kebab), ty))
} else { } else {
@ -47,35 +46,33 @@ fn append_message(messages: &[DescriptorProto]) -> Valid<Vec<Record>, anyhow::Er
} }
pub fn handle_types(config: Config, proto: &[FileDescriptorSet], package: String) -> Valid<Config, anyhow::Error, anyhow::Error> { pub fn handle_types(config: Config, proto: &[FileDescriptorSet], package: String) -> Valid<Config, anyhow::Error, anyhow::Error> {
Valid::succeed(config) Valid::from_iter(proto.iter(), |set| {
.and_then(|config| { let mut map = BTreeMap::new();
Valid::from_iter(proto.iter(), |set| { let mut records = BTreeSet::new();
let mut map = BTreeMap::new(); Valid::from_iter(set.file.iter(), |file| {
let mut records = BTreeSet::new(); append_enums(&file.enum_type).and_then(|varients| {
Valid::from_iter(set.file.iter(), |file| { append_message(&file.message_type)
append_enums(&file.enum_type).and_then(|varients| { .and_then(|recs| {
append_message(&file.message_type) map.extend(varients);
.and_then(|recs| { records.extend(BTreeSet::from_iter(recs.into_iter()));
map.extend(varients); Valid::succeed(())
records.extend(BTreeSet::from_iter(recs.into_iter()));
Valid::succeed(())
})
})
})
.and_then(|_| {
Valid::succeed(Interface {
name: "type".to_string(),
varients: map,
records,
..Default::default()
})
}) })
}) })
}).and_then(|v| { })
.and_then(|_| {
Valid::succeed(Interface {
name: "type".to_string(),
varients: map,
records,
..Default::default()
})
})
}).and_then(|mut interfaces| {
interfaces.extend(config.interfaces.into_iter());
Valid::succeed(Config { Valid::succeed(Config {
package, package,
interfaces: v.into_iter().collect(), interfaces: interfaces.into_iter().collect(),
world: Default::default(), ..config
}) })
}) })
} }

@ -53,8 +53,7 @@ mod t {
#[test] #[test]
fn bar() { fn bar() {
let relative = format!("{}/src/proto/fixtures",env!("CARGO_MANIFEST_DIR")); let relative = format!("{}/src/proto/fixtures",env!("CARGO_MANIFEST_DIR"));
let x = std::fs::read_to_string(format!("{}/address.proto", relative)).unwrap(); let proto = protox::compile([format!("{}/address.proto", relative)], [relative]).unwrap();
let proto = protox::compile([format!("{}/address.proto", relative)], [relative]).unwrap();
let proto = Proto::new([proto]); let proto = Proto::new([proto]);
let config = proto.to_config().to_result().unwrap(); let config = proto.to_config().to_result().unwrap();
println!("{}", config.to_wit()); println!("{}", config.to_wit());

@ -1,7 +0,0 @@
use tailcall_valid::Valid;
pub trait Transform {
type Value;
type Error;
fn transform(&self, value: Self::Value) -> Valid<Self::Value, Self::Error, Self::Error>;
}