Skip to content

Commit

Permalink
ST anyhow
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasavila00 committed May 10, 2024
1 parent b8ee59a commit 53716bc
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 43 deletions.
90 changes: 49 additions & 41 deletions packages/beff-core/src/subtyping/to_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use std::{
rc::Rc,
};

use anyhow::bail;

use crate::{
ast::json_schema::{JsonSchema, JsonSchemaConst, Optionality},
Validator,
Expand Down Expand Up @@ -170,11 +172,11 @@ impl<'a, 'b> SchemerContext<'a, 'b> {
}
}

fn mapping_atom_schema(&mut self, mt: &Rc<MappingAtomicType>) -> JsonSchema {
fn mapping_atom_schema(&mut self, mt: &Rc<MappingAtomicType>) -> anyhow::Result<JsonSchema> {
let mut acc: Vec<(String, Optionality<JsonSchema>)> = vec![];

for (k, v) in mt.vs.iter() {
let schema = self.convert_to_schema(v, None);
let schema = self.convert_to_schema(v, None)?;
let ty = if v.has_void() {
schema.optional()
} else {
Expand All @@ -184,18 +186,18 @@ impl<'a, 'b> SchemerContext<'a, 'b> {
}

let rest = if mt.rest.is_empty(self.ctx.0) {
panic!("rest should not be empty, all records are open")
bail!("rest should not be empty, all records are open")
} else if mt.rest.is_any() {
None
} else {
let schema = self.convert_to_schema(&mt.rest, None);
let schema = self.convert_to_schema(&mt.rest, None)?;
Some(Box::new(schema))
};

JsonSchema::Object {
Ok(JsonSchema::Object {
vs: BTreeMap::from_iter(acc),
rest,
}
})
}

// fn to_schema_mapping(&mut self, bdd: &Rc<Bdd>) -> JsonSchema {
Expand All @@ -213,13 +215,13 @@ impl<'a, 'b> SchemerContext<'a, 'b> {
left: &Rc<Bdd>,
middle: &Rc<Bdd>,
right: &Rc<Bdd>,
) -> JsonSchema {
) -> anyhow::Result<JsonSchema> {
let mt = match atom.as_ref() {
Atom::Mapping(a) => self.ctx.0.get_mapping_atomic(*a).clone(),
_ => unreachable!(),
};

let explained_sts = self.mapping_atom_schema(&mt);
let explained_sts = self.mapping_atom_schema(&mt)?;

let mut acc = vec![];

Expand All @@ -237,7 +239,7 @@ impl<'a, 'b> SchemerContext<'a, 'b> {
right,
} => {
let ty = vec![explained_sts.clone()].into_iter().chain(vec![
self.convert_to_schema_mapping_node(atom, left, middle, right)
self.convert_to_schema_mapping_node(atom, left, middle, right)?
]);
acc.push(JsonSchema::all_of(ty.collect()));
}
Expand All @@ -247,7 +249,7 @@ impl<'a, 'b> SchemerContext<'a, 'b> {
// noop
}
Bdd::True | Bdd::Node { .. } => {
acc.push(self.convert_to_schema_mapping(middle));
acc.push(self.convert_to_schema_mapping(middle)?);
}
}
match right.as_ref() {
Expand All @@ -265,15 +267,15 @@ impl<'a, 'b> SchemerContext<'a, 'b> {
} => {
let ty = JsonSchema::all_of(vec![
JsonSchema::StNot(Box::new(explained_sts)),
self.convert_to_schema_mapping_node(atom, left, middle, right),
self.convert_to_schema_mapping_node(atom, left, middle, right)?,
]);
acc.push(ty)
}
}
JsonSchema::any_of(acc)
Ok(JsonSchema::any_of(acc))
}

fn convert_to_schema_mapping(&mut self, bdd: &Rc<Bdd>) -> JsonSchema {
fn convert_to_schema_mapping(&mut self, bdd: &Rc<Bdd>) -> anyhow::Result<JsonSchema> {
match bdd.as_ref() {
Bdd::True => todo!(),
Bdd::False => todo!(),
Expand All @@ -286,29 +288,31 @@ impl<'a, 'b> SchemerContext<'a, 'b> {
}
}

fn list_atom_schema(&mut self, mt: &Rc<ListAtomic>) -> JsonSchema {
fn list_atom_schema(&mut self, mt: &Rc<ListAtomic>) -> anyhow::Result<JsonSchema> {
if mt.prefix_items.is_empty() {
if mt.items.is_any() {
return JsonSchema::AnyArrayLike;
return Ok(JsonSchema::AnyArrayLike);
}
return JsonSchema::Array(Box::new(self.convert_to_schema(&mt.items, None)));
return Ok(JsonSchema::Array(Box::new(
self.convert_to_schema(&mt.items, None)?,
)));
}

let prefix_items = mt
.prefix_items
.iter()
.map(|it| self.convert_to_schema(it, None))
.collect();
.collect::<anyhow::Result<Vec<_>>>()?;

let items = if mt.items.is_never() {
None
} else {
Some(Box::new(self.convert_to_schema(&mt.items, None)))
Some(Box::new(self.convert_to_schema(&mt.items, None)?))
};
JsonSchema::Tuple {
Ok(JsonSchema::Tuple {
prefix_items,
items,
}
})
}

// fn to_schema_list(&mut self, bdd: &Rc<Bdd>) -> JsonSchema {
Expand All @@ -326,13 +330,13 @@ impl<'a, 'b> SchemerContext<'a, 'b> {
left: &Rc<Bdd>,
middle: &Rc<Bdd>,
right: &Rc<Bdd>,
) -> JsonSchema {
) -> anyhow::Result<JsonSchema> {
let lt = match atom.as_ref() {
Atom::List(a) => self.ctx.0.get_list_atomic(*a).clone(),
_ => unreachable!(),
};

let explained_sts = self.list_atom_schema(&lt);
let explained_sts = self.list_atom_schema(&lt)?;

let mut acc = vec![];

Expand All @@ -350,7 +354,7 @@ impl<'a, 'b> SchemerContext<'a, 'b> {
right,
} => {
let ty = vec![explained_sts.clone()].into_iter().chain(vec![
self.convert_to_schema_list_node(atom, left, middle, right)
self.convert_to_schema_list_node(atom, left, middle, right)?
]);
acc.push(JsonSchema::all_of(ty.collect()));
}
Expand All @@ -361,7 +365,7 @@ impl<'a, 'b> SchemerContext<'a, 'b> {
// noop
}
Bdd::True | Bdd::Node { .. } => {
acc.push(self.convert_to_schema_list(middle));
acc.push(self.convert_to_schema_list(middle)?);
}
}
match right.as_ref() {
Expand All @@ -379,14 +383,14 @@ impl<'a, 'b> SchemerContext<'a, 'b> {
} => {
let ty = JsonSchema::all_of(vec![
JsonSchema::StNot(Box::new(explained_sts)),
self.convert_to_schema_list_node(atom, left, middle, right),
self.convert_to_schema_list_node(atom, left, middle, right)?,
]);
acc.push(ty)
}
}
JsonSchema::any_of(acc)
Ok(JsonSchema::any_of(acc))
}
fn convert_to_schema_list(&mut self, bdd: &Rc<Bdd>) -> JsonSchema {
fn convert_to_schema_list(&mut self, bdd: &Rc<Bdd>) -> anyhow::Result<JsonSchema> {
match bdd.as_ref() {
Bdd::True => todo!(),
Bdd::False => todo!(),
Expand All @@ -399,9 +403,9 @@ impl<'a, 'b> SchemerContext<'a, 'b> {
}
}

fn convert_to_schema_no_cache(&mut self, ty: &SemType) -> JsonSchema {
fn convert_to_schema_no_cache(&mut self, ty: &SemType) -> anyhow::Result<JsonSchema> {
if ty.all == 0 && ty.subtype_data.is_empty() {
return JsonSchema::StNever;
return Ok(JsonSchema::StNever);
}

let mut acc = BTreeSet::new();
Expand Down Expand Up @@ -469,18 +473,22 @@ impl<'a, 'b> SchemerContext<'a, 'b> {
}
}
ProperSubtype::Mapping(bdd) => {
let mapping_ty = self.convert_to_schema_mapping(bdd);
let mapping_ty = self.convert_to_schema_mapping(bdd)?;
acc.insert(mapping_ty);
}
ProperSubtype::List(bdd) => {
acc.insert(self.convert_to_schema_list(bdd));
acc.insert(self.convert_to_schema_list(bdd)?);
}
};
}

JsonSchema::any_of(acc.into_iter().collect())
Ok(JsonSchema::any_of(acc.into_iter().collect()))
}
pub fn convert_to_schema(&mut self, ty: &Rc<SemType>, name: Option<&str>) -> JsonSchema {
pub fn convert_to_schema(
&mut self,
ty: &Rc<SemType>,
name: Option<&str>,
) -> anyhow::Result<JsonSchema> {
let new_name = match name {
Some(n) => n.to_string(),
None => {
Expand All @@ -490,25 +498,25 @@ impl<'a, 'b> SchemerContext<'a, 'b> {
};
if let Some(mater) = self.schemer_memo.get(ty) {
match mater {
SchemaMemo::Schema(mater) => return mater.clone(),
SchemaMemo::Schema(mater) => return Ok(mater.clone()),
SchemaMemo::Undefined(ref_name) => {
self.recursive_validators.insert(ref_name.clone());
return JsonSchema::Ref(ref_name.into());
return Ok(JsonSchema::Ref(ref_name.into()));
}
}
} else {
self.schemer_memo
.insert(ty.clone(), SchemaMemo::Undefined(new_name.clone()));
}
let schema = self.convert_to_schema_no_cache(ty);
let schema = self.convert_to_schema_no_cache(ty)?;
self.schemer_memo
.insert(ty.clone(), SchemaMemo::Schema(schema.clone()));
self.validators.push(Validator {
name: new_name,
schema: schema.clone(),
});

schema
Ok(schema)
}
}

Expand All @@ -517,23 +525,23 @@ pub fn to_validators(
ty: &Rc<SemType>,
name: &str,
counter: &mut usize,
) -> (Validator, Vec<Validator>) {
) -> anyhow::Result<(Validator, Vec<Validator>)> {
let mut schemer = SchemerContext::new(ctx, counter);
let out = schemer.convert_to_schema(ty, Some(name));
let out = schemer.convert_to_schema(ty, Some(name))?;
let vs: Vec<Validator> = schemer
.validators
.into_iter()
.filter(|it| schemer.recursive_validators.contains(&it.name))
.collect();

let vs = vs.into_iter().filter(|it| it.name != name).collect();
(
Ok((
Validator {
name: name.into(),
schema: out,
},
vs,
)
))
}
fn maybe_not(it: JsonSchema, add_not: bool) -> JsonSchema {
if add_not {
Expand Down
7 changes: 5 additions & 2 deletions packages/beff-core/src/type_to_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1361,7 +1361,7 @@ impl<'a, 'b, R: FileManager> TypeToSchema<'a, 'b, R> {
SymbolExport::ValueExpr { expr, .. } => self.typeof_expr(expr, false),
SymbolExport::StarOfOtherFile { .. } => todo!(),
SymbolExport::SomethingOfOtherFile { .. } => todo!(),
SymbolExport::ExprDecl { .. } => todo!(),
SymbolExport::ExprDecl { ty, .. } => self.convert_ts_type(ty),
};
self.current_file = old_file;
ty
Expand Down Expand Up @@ -1523,7 +1523,10 @@ impl<'a, 'b, R: FileManager> TypeToSchema<'a, 'b, R> {
DiagnosticInfoMessage::NeverCannotBeConvertedToJsonSchema,
);
}
let (head, tail) = to_validators(ctx, &access_st, "AnyName", self.counter);
let (head, tail) =
to_validators(ctx, &access_st, "AnyName", self.counter).map_err(|any| {
self.box_error(span, DiagnosticInfoMessage::AnyhowError(any.to_string()))
})?;
for t in tail {
self.insert_definition(t.name.clone(), t.schema)?;
}
Expand Down

0 comments on commit 53716bc

Please sign in to comment.