fix add_fields population
This commit is contained in:
parent
c5a178da1a
commit
d3658fd6f0
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -184,6 +184,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
"convert_case",
|
||||
"derive_setters",
|
||||
"lazy_static",
|
||||
"macros",
|
||||
"oapi",
|
||||
|
@ -22,6 +22,7 @@ lazy_static = "1.5.0"
|
||||
base64 = "0.22.1"
|
||||
strum_macros = "0.26.4"
|
||||
macros = {path = "macros"}
|
||||
derive_setters = "0.1.6"
|
||||
|
||||
[workspace]
|
||||
members = [".", "macros"]
|
||||
|
@ -42,7 +42,6 @@ impl Ord for Interface {
|
||||
pub struct Record {
|
||||
pub name: String,
|
||||
pub fields: BTreeSet<Field>,
|
||||
pub added_fields: BTreeSet<Field>,
|
||||
}
|
||||
|
||||
impl PartialOrd for Record {
|
||||
@ -85,7 +84,7 @@ pub struct Parameter {
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight)]
|
||||
pub struct Field {
|
||||
pub name: String,
|
||||
pub field_type: WitType,
|
||||
pub field_type: String,
|
||||
}
|
||||
|
||||
impl PartialOrd for Field {
|
||||
|
@ -1,45 +1,101 @@
|
||||
use std::collections::BTreeSet;
|
||||
use base64::Engine;
|
||||
use tailcall_valid::{Valid, Validator};
|
||||
use crate::config::config::{Config, Field, Interface, Record};
|
||||
use crate::config::schema_document::{SchemaDocument, 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<Config, anyhow::Error, anyhow::Error> {
|
||||
pub fn fix_args(config: SchemaDocument) -> Valid<SchemaDocument, anyhow::Error, anyhow::Error> {
|
||||
Valid::succeed(config)
|
||||
.and_then(|mut config| {
|
||||
Valid::from_iter(config.interfaces.iter(), |interface| {
|
||||
Valid::from_iter(interface.records.iter(), |record| {
|
||||
Valid::from_iter(record.fields.iter(), |field| {
|
||||
Valid::from_iter(config.interfaces.iter().cloned().collect::<Vec<_>>(), |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), interface.clone())
|
||||
.and_then(|new_interface| {
|
||||
Valid::succeed(Some(new_interface))
|
||||
.try_fold(&(&config, &interface, &record, &field, &field.field_type), Field::default())
|
||||
.and_then(|field| {
|
||||
Valid::succeed(Some(field))
|
||||
})
|
||||
} else {
|
||||
}else {
|
||||
Valid::succeed(None)
|
||||
}
|
||||
})
|
||||
})
|
||||
}).and_then(|x| {
|
||||
let x = x.into_iter().flatten().into_iter().flatten().filter_map(|x| x).collect::<Vec<_>>();
|
||||
}).and_then(|v| {
|
||||
let fields = v.into_iter().filter_map(|x| x).collect();
|
||||
record.added_fields = fields;
|
||||
|
||||
let mut map = BTreeSet::new();
|
||||
for interface in x {
|
||||
map.insert(interface);
|
||||
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 = config.interfaces.merge_right(map);
|
||||
config.interfaces = new_interfaces;*/
|
||||
// config.interfaces = config.interfaces.merge_right(map);
|
||||
|
||||
Valid::succeed(config)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn fix_field<'a>() -> TryFold<'a, (&'a Config, &'a Interface, &'a Record, &'a Field, &'a WitType), Interface, anyhow::Error> {
|
||||
TryFold::<(&Config, &Interface, &Record, &Field, &WitType), Interface, anyhow::Error>::new(move |(config, interface, rec, field, wit), mut o| {
|
||||
/*
|
||||
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 SchemaDocument, &'a Interface, &'a Record, &'a Field, &'a WitType), Field, anyhow::Error> {
|
||||
TryFold::<(&SchemaDocument, &Interface, &Record, &Field, &WitType), Field, anyhow::Error>::new(move |(config, interface, rec, field, wit), mut o| {
|
||||
match &wit {
|
||||
WitType::Option(x) => {
|
||||
return fix_field().try_fold(&(*config, *interface, *rec, *field, x), o);
|
||||
@ -63,30 +119,23 @@ fn fix_field<'a>() -> TryFold<'a, (&'a Config, &'a Interface, &'a Record, &'a Fi
|
||||
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((*interface).clone(), |mut a, b| {
|
||||
a.records.extend(b.records);
|
||||
a
|
||||
.and_then(|v| Valid::succeed(v.into_iter().fold((*field).clone(), |mut 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 {
|
||||
} else {
|
||||
field.name.clone()
|
||||
};
|
||||
let name = format!("{}-{}", rec.name, field_name);
|
||||
|
||||
|
||||
let new_field = Field {
|
||||
name,
|
||||
field_type: WitType::Record(records.clone()),
|
||||
};
|
||||
let mut rec = (*rec).clone();
|
||||
rec.added_fields.insert(new_field);
|
||||
// let mut filtered_records = o.records.into_iter().filter(|r| r.name == rec.name).collect::<Vec<_>>();
|
||||
// filtered_records.push(rec);
|
||||
o.records.remove(&rec);
|
||||
o.records.insert(rec);
|
||||
Valid::succeed(o)
|
||||
Valid::succeed(new_field)
|
||||
}
|
||||
// Ideally this case should never happen,
|
||||
// but we should always throw an error to avoid infinite recursion
|
||||
|
@ -1,12 +1,12 @@
|
||||
use std::collections::BTreeSet;
|
||||
use anyhow::{anyhow, Error};
|
||||
use tailcall_valid::{Valid, Validator};
|
||||
use crate::config::config::{Config, Field, Interface, Record};
|
||||
use crate::config::schema_document::{SchemaDocument, Field, Interface, Record};
|
||||
use crate::config::wit_types::WitType;
|
||||
use crate::ser::OpenApiSpec;
|
||||
|
||||
pub fn handle_types(config: Config, spec: &OpenApiSpec) -> Valid<Config, Error, Error> {
|
||||
Valid::succeed(config).and_then(|mut config: Config| {
|
||||
pub fn handle_types(config: SchemaDocument, spec: &OpenApiSpec) -> Valid<SchemaDocument, Error, Error> {
|
||||
Valid::succeed(config).and_then(|mut config: SchemaDocument| {
|
||||
Valid::from_option(spec.components.as_ref(), anyhow!("Components are required"))
|
||||
.and_then(|v| Valid::from_option(v.schemas.as_ref(), anyhow!("Schemas are required")))
|
||||
.and_then(|schemas| {
|
||||
|
@ -1,5 +1,7 @@
|
||||
pub mod config;
|
||||
pub mod schema_document;
|
||||
pub mod wit_types;
|
||||
pub mod to_wit;
|
||||
pub mod fixargs;
|
||||
pub mod handle_files;
|
||||
pub mod config;
|
||||
pub mod to_config;
|
||||
|
101
src/config/schema_document.rs
Normal file
101
src/config/schema_document.rs
Normal file
@ -0,0 +1,101 @@
|
||||
use std::collections::BTreeSet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use macros::MergeRight;
|
||||
use crate::config::wit_types::WitType;
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight)]
|
||||
pub struct SchemaDocument {
|
||||
pub package: String,
|
||||
pub interfaces: BTreeSet<Interface>,
|
||||
pub world: World,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight)]
|
||||
pub struct World {
|
||||
pub name: String,
|
||||
pub uses: Vec<UseStatement>,
|
||||
pub imports: Vec<Interface>,
|
||||
pub exports: Vec<Interface>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight, derive_setters::Setters)]
|
||||
pub struct Interface {
|
||||
pub name: String,
|
||||
pub records: BTreeSet<Record>,
|
||||
pub uses: Vec<UseStatement>,
|
||||
pub functions: Vec<Function>,
|
||||
}
|
||||
|
||||
impl PartialOrd for Interface {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.name.cmp(&other.name))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Interface {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.name.cmp(&other.name)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight)]
|
||||
pub struct Record {
|
||||
pub name: String,
|
||||
pub fields: BTreeSet<Field>,
|
||||
pub added_fields: BTreeSet<Field>,
|
||||
}
|
||||
|
||||
impl PartialOrd for Record {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.name.cmp(&other.name))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Record {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.name.cmp(&other.name)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight)]
|
||||
pub struct UseStatement {
|
||||
pub name: String,
|
||||
pub items: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight)]
|
||||
pub struct Function {
|
||||
pub name: String,
|
||||
pub parameters: Vec<Parameter>,
|
||||
pub return_type: ReturnTy,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight)]
|
||||
pub struct ReturnTy {
|
||||
pub return_type: String,
|
||||
pub error_type: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight)]
|
||||
pub struct Parameter {
|
||||
pub name: String,
|
||||
pub parameter_type: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, MergeRight)]
|
||||
pub struct Field {
|
||||
pub name: String,
|
||||
pub field_type: WitType,
|
||||
}
|
||||
|
||||
impl PartialOrd for Field {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.name.cmp(&other.name))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for Field {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.name.cmp(&other.name)
|
||||
}
|
||||
}
|
9
src/config/to_config.rs
Normal file
9
src/config/to_config.rs
Normal file
@ -0,0 +1,9 @@
|
||||
use tailcall_valid::Valid;
|
||||
use crate::config::config::Config;
|
||||
use crate::config::schema_document::SchemaDocument;
|
||||
|
||||
impl SchemaDocument {
|
||||
pub fn to_config(&self) -> Valid<Config, anyhow::Error, anyhow::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
use crate::config::config::{Config, Field, Function, Interface, Parameter, Record, ReturnTy, UseStatement, World};
|
||||
use crate::config::schema_document::{SchemaDocument, Field, Function, Interface, Parameter, Record, ReturnTy, UseStatement, World};
|
||||
use crate::config::wit_types::WitType;
|
||||
use convert_case::{Case, Casing};
|
||||
use std::collections::HashSet;
|
||||
@ -41,8 +41,8 @@ fn generate_wit_name(name: &str) -> String {
|
||||
final_name
|
||||
}
|
||||
|
||||
impl ToWit for Config {
|
||||
fn to_wit(&self) -> String {
|
||||
impl SchemaDocument {
|
||||
pub fn to_wit(&self) -> String {
|
||||
let package = format!("package {};\n", generate_wit_name(&self.package));
|
||||
let world = self.world.to_wit();
|
||||
let interfaces = self
|
||||
@ -56,8 +56,8 @@ impl ToWit for Config {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToWit for World {
|
||||
fn to_wit(&self) -> String {
|
||||
impl World {
|
||||
pub fn to_wit(&self) -> String {
|
||||
if self == &World::default() {
|
||||
return String::new();
|
||||
}
|
||||
@ -93,8 +93,8 @@ impl ToWit for World {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToWit for Interface {
|
||||
fn to_wit(&self) -> String {
|
||||
impl Interface {
|
||||
pub fn to_wit(&self) -> String {
|
||||
let uses = self
|
||||
.uses
|
||||
.iter()
|
||||
@ -126,8 +126,8 @@ impl ToWit for Interface {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToWit for Record {
|
||||
fn to_wit(&self) -> String {
|
||||
impl Record {
|
||||
pub fn to_wit(&self) -> String {
|
||||
let fields = self
|
||||
.fields
|
||||
.iter()
|
||||
@ -139,8 +139,8 @@ impl ToWit for Record {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToWit for Field {
|
||||
fn to_wit(&self) -> String {
|
||||
impl Field {
|
||||
pub fn to_wit(&self) -> String {
|
||||
format!(
|
||||
"{}: {}",
|
||||
generate_wit_name(&self.name),
|
||||
@ -150,8 +150,8 @@ impl ToWit for Field {
|
||||
}
|
||||
|
||||
|
||||
impl ToWit for Function {
|
||||
fn to_wit(&self) -> String {
|
||||
impl Function {
|
||||
pub fn to_wit(&self) -> String {
|
||||
let params = self
|
||||
.parameters
|
||||
.iter()
|
||||
@ -174,8 +174,8 @@ impl ToWit for Function {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToWit for ReturnTy {
|
||||
fn to_wit(&self) -> String {
|
||||
impl ReturnTy {
|
||||
pub fn to_wit(&self) -> String {
|
||||
if self.error_type.is_empty() {
|
||||
self.return_type.clone()
|
||||
} else {
|
||||
@ -188,8 +188,8 @@ impl ToWit for ReturnTy {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToWit for Parameter {
|
||||
fn to_wit(&self) -> String {
|
||||
impl Parameter {
|
||||
pub fn to_wit(&self) -> String {
|
||||
format!(
|
||||
"{}: {}",
|
||||
generate_wit_name(&self.name),
|
||||
@ -198,8 +198,8 @@ impl ToWit for Parameter {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToWit for UseStatement {
|
||||
fn to_wit(&self) -> String {
|
||||
impl UseStatement {
|
||||
pub fn to_wit(&self) -> String {
|
||||
format!(
|
||||
"use {}.{{{}}};",
|
||||
generate_wit_name(&self.name),
|
||||
@ -212,8 +212,8 @@ impl ToWit for UseStatement {
|
||||
}
|
||||
}
|
||||
|
||||
impl ToWit for WitType {
|
||||
fn to_wit(&self) -> String {
|
||||
impl WitType {
|
||||
pub fn to_wit(&self) -> String {
|
||||
match self {
|
||||
WitType::Bool => "bool".to_string(),
|
||||
WitType::U8 => "u8".to_string(),
|
||||
@ -274,7 +274,7 @@ impl ToWit for WitType {
|
||||
.join(", ")
|
||||
),
|
||||
WitType::Handle(name) => format!("handle<{}>", generate_wit_name(name)),
|
||||
WitType::TypeAlias(name, inner) => format!("type {} = {}", generate_wit_name(name), inner.to_wit()),
|
||||
WitType::TypeAlias(name, inner) => format!("type {} = {}", generate_wit_name(name), inner.to_wit()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tailcall_valid::{Valid, Validator};
|
||||
use crate::config::to_wit::ToWit;
|
||||
|
||||
use crate::ser::{OpenApiSpec, Schema};
|
||||
|
||||
|
@ -25,7 +25,7 @@ impl<A> MergeRight for Vec<A> {
|
||||
|
||||
impl<V> MergeRight for BTreeSet<V>
|
||||
where
|
||||
V: Ord,
|
||||
V: Ord + MergeRight,
|
||||
{
|
||||
fn merge_right(self, mut other: Self) -> Self {
|
||||
other.extend(self);
|
||||
|
11
src/proto.rs
11
src/proto.rs
@ -1,13 +1,13 @@
|
||||
use anyhow::Error;
|
||||
use tailcall_valid::{Valid, Validator};
|
||||
|
||||
use crate::config::config::Config;
|
||||
use crate::config::schema_document::SchemaDocument;
|
||||
use crate::config::fixargs::fix_args;
|
||||
use crate::config::handle_files::handle_types;
|
||||
use crate::ser::OpenApiSpec;
|
||||
|
||||
fn to_config(spec: OpenApiSpec) -> Valid<Config, Error, Error> {
|
||||
Valid::succeed(Config::default())
|
||||
fn to_config(spec: OpenApiSpec) -> Valid<SchemaDocument, Error, Error> {
|
||||
Valid::succeed(SchemaDocument::default())
|
||||
.and_then(|config| handle_types(config, &spec))
|
||||
.and_then(|config| fix_args(config))
|
||||
}
|
||||
@ -16,7 +16,6 @@ fn to_config(spec: OpenApiSpec) -> Valid<Config, Error, Error> {
|
||||
mod t {
|
||||
use tailcall_valid::Validator;
|
||||
|
||||
use crate::config::to_wit::ToWit;
|
||||
use crate::proto::to_config;
|
||||
use crate::ser::OpenApiSpec;
|
||||
|
||||
@ -30,8 +29,8 @@ mod t {
|
||||
match res.as_mut() {
|
||||
Ok(v) => {
|
||||
println!("{}", serde_json::to_string_pretty(v).unwrap());
|
||||
// v.package = "api:todos@1.0.0".to_string();
|
||||
// println!("{}", v.to_wit());
|
||||
v.package = "api:todos@1.0.0".to_string();
|
||||
println!("{}", v.to_wit());
|
||||
// let mut resolve = Resolve::new();
|
||||
// resolve.push_str("foox.wit", &v.to_wit()).expect("TODO: panic message`");
|
||||
// println!("{:#?}", resolve);
|
||||
|
Loading…
Reference in New Issue
Block a user