11//! Wasm bindings for models of double theories.
22
33use all_the_same:: all_the_same;
4+ use derive_more:: { From , TryInto } ;
45use uuid:: Uuid ;
56
67use serde:: { Deserialize , Serialize } ;
78use tsify_next:: Tsify ;
89use wasm_bindgen:: prelude:: * ;
910
10- use super :: theory:: * ;
1111use catlog:: dbl:: model:: { self as dbl_model, FgDblModel , InvalidDiscreteDblModel } ;
1212use catlog:: one:: fin_category:: UstrFinCategory ;
13- use catlog:: one:: Path ;
14- use catlog:: one:: { Category as _, FgCategory } ;
15- use catlog:: validate:: { self , Validate } ;
13+ use catlog:: one:: { Category as _, FgCategory , Path } ;
14+ use catlog:: validate:: Validate ;
15+
16+ use super :: result:: JsResult ;
17+ use super :: theory:: { DblTheory , DblTheoryBox , MorType , ObType } ;
1618
1719/// An object in a model of a double theory.
18- #[ derive( Debug , Serialize , Deserialize , Tsify ) ]
20+ #[ derive( Debug , PartialEq , Eq , Serialize , Deserialize , Tsify ) ]
1921#[ serde( tag = "tag" , content = "content" ) ]
2022#[ tsify( into_wasm_abi, from_wasm_abi) ]
2123pub enum Ob {
@@ -27,7 +29,7 @@ pub enum Ob {
2729}
2830
2931/// A morphism in a model of a double theory.
30- #[ derive( Debug , Serialize , Deserialize , Tsify ) ]
32+ #[ derive( Debug , PartialEq , Eq , Serialize , Deserialize , Tsify ) ]
3133#[ serde( tag = "tag" , content = "content" ) ]
3234#[ tsify( into_wasm_abi, from_wasm_abi) ]
3335pub enum Mor {
@@ -113,36 +115,19 @@ pub struct MorDecl {
113115 pub cod : Option < Ob > ,
114116}
115117
116- type UuidDiscreteDblModel = dbl_model:: DiscreteDblModel < Uuid , UstrFinCategory > ;
118+ pub ( crate ) type DiscreteDblModel = dbl_model:: DiscreteDblModel < Uuid , UstrFinCategory > ;
117119
118120/** A box containing a model of a double theory of any kind.
119121
120122See [`DblTheoryBox`] for motivation.
121123 */
124+ #[ derive( From , TryInto ) ]
125+ #[ try_into( ref) ]
122126pub enum DblModelBox {
123- Discrete ( UuidDiscreteDblModel ) ,
127+ Discrete ( DiscreteDblModel ) ,
124128 // DiscreteTab(()), // TODO: Not yet implemented.
125129}
126130
127- /// Converts from a model of a discrete double theory.
128- impl From < UuidDiscreteDblModel > for DblModel {
129- fn from ( model : UuidDiscreteDblModel ) -> Self {
130- DblModel ( DblModelBox :: Discrete ( model) )
131- }
132- }
133-
134- /// Converts into a model of a dicrete double theory.
135- impl < ' a > TryFrom < & ' a DblModel > for & ' a UuidDiscreteDblModel {
136- type Error = String ;
137-
138- fn try_from ( model : & ' a DblModel ) -> Result < Self , Self :: Error > {
139- match & model. 0 {
140- DblModelBox :: Discrete ( model) => Ok ( model) ,
141- //_ => Err("Cannot cast into a model of a discrete double theory".into()),
142- }
143- }
144- }
145-
146131/// Wasm bindings for a model of a double theory.
147132#[ wasm_bindgen]
148133pub struct DblModel ( #[ wasm_bindgen( skip) ] pub DblModelBox ) ;
@@ -153,9 +138,7 @@ impl DblModel {
153138 #[ wasm_bindgen( constructor) ]
154139 pub fn new ( theory : & DblTheory ) -> Self {
155140 Self ( match & theory. 0 {
156- DblTheoryBox :: Discrete ( th) => {
157- DblModelBox :: Discrete ( UuidDiscreteDblModel :: new ( th. clone ( ) ) )
158- }
141+ DblTheoryBox :: Discrete ( th) => DiscreteDblModel :: new ( th. clone ( ) ) . into ( ) ,
159142 DblTheoryBox :: DiscreteTab ( _) => panic ! ( "Not implemented" ) ,
160143 } )
161144 }
@@ -178,10 +161,12 @@ impl DblModel {
178161 DblModelBox :: [ Discrete ] ( model) => {
179162 let mor_type = decl. mor_type. try_into( ) ?;
180163 let res = model. make_mor( decl. id, mor_type) ;
181- let dom = decl. dom. map( |ob| ob. try_into( ) ) . transpose( ) ?;
182- let cod = decl. cod. map( |ob| ob. try_into( ) ) . transpose( ) ?;
183- model. update_dom( decl. id, dom) ;
184- model. update_cod( decl. id, cod) ;
164+ if let Some ( dom) = decl. dom. map( |ob| ob. try_into( ) ) . transpose( ) ? {
165+ model. set_dom( decl. id, dom) ;
166+ }
167+ if let Some ( cod) = decl. cod. map( |ob| ob. try_into( ) ) . transpose( ) ? {
168+ model. set_cod( decl. id, cod) ;
169+ }
185170 Ok ( res)
186171 }
187172 } )
@@ -249,48 +234,68 @@ impl DblModel {
249234
250235 /// Validates that the model is well defined.
251236 #[ wasm_bindgen]
252- pub fn validate ( & self ) -> Vec < InvalidDiscreteDblModel < Uuid > > {
237+ pub fn validate ( & self ) -> ModelValidationResult {
253238 all_the_same ! ( match & self . 0 {
254- DblModelBox :: [ Discrete ] ( model) => validate:: unwrap_errors( model. validate( ) )
239+ DblModelBox :: [ Discrete ] ( model) => {
240+ let res = model. validate( ) ;
241+ ModelValidationResult ( res. map_err( |errs| errs. into( ) ) . into( ) )
242+ }
255243 } )
256244 }
257245}
258246
247+ /// Result of validating a model of a double theory.
248+ #[ derive( Serialize , Deserialize , Tsify ) ]
249+ #[ tsify( into_wasm_abi, from_wasm_abi) ]
250+ pub struct ModelValidationResult ( pub JsResult < ( ) , Vec < InvalidDiscreteDblModel < Uuid > > > ) ;
251+
259252#[ cfg( test) ]
260- mod tests {
253+ pub ( crate ) mod tests {
261254 use super :: * ;
262255 use crate :: theories:: * ;
263256
264- #[ test]
265- fn model_schema ( ) {
266- let th = ThSchema :: new ( ) . theory ( ) ;
267- let mut model = DblModel :: new ( & th) ;
268- let ( x, y, a) = ( Uuid :: now_v7 ( ) , Uuid :: now_v7 ( ) , Uuid :: now_v7 ( ) ) ;
257+ pub ( crate ) fn sch_walking_attr ( th : & DblTheory , ids : [ Uuid ; 3 ] ) -> DblModel {
258+ let mut model = DblModel :: new ( th) ;
259+ let [ attr, entity, attr_type] = ids;
269260 assert ! ( model
270261 . add_ob( ObDecl {
271- id: x ,
262+ id: entity ,
272263 ob_type: ObType :: Basic ( "Entity" . into( ) ) ,
273264 } )
274265 . is_ok( ) ) ;
275266 assert ! ( model
276267 . add_ob( ObDecl {
277- id: y ,
268+ id: attr_type ,
278269 ob_type: ObType :: Basic ( "AttrType" . into( ) ) ,
279270 } )
280271 . is_ok( ) ) ;
281272 assert ! ( model
282273 . add_mor( MorDecl {
283- id: a ,
274+ id: attr ,
284275 mor_type: MorType :: Basic ( "Attr" . into( ) ) ,
285- dom: Some ( Ob :: Basic ( x ) ) ,
286- cod: Some ( Ob :: Basic ( y ) ) ,
276+ dom: Some ( Ob :: Basic ( entity ) ) ,
277+ cod: Some ( Ob :: Basic ( attr_type ) ) ,
287278 } )
288279 . is_ok( ) ) ;
280+ model
281+ }
282+
283+ #[ test]
284+ fn model_schema ( ) {
285+ let th = ThSchema :: new ( ) . theory ( ) ;
286+ let [ a, x, y] = [ Uuid :: now_v7 ( ) , Uuid :: now_v7 ( ) , Uuid :: now_v7 ( ) ] ;
287+ let model = sch_walking_attr ( & th, [ a, x, y] ) ;
288+
289289 assert_eq ! ( model. has_ob( Ob :: Basic ( x) ) , Ok ( true ) ) ;
290290 assert_eq ! ( model. has_mor( Mor :: Basic ( a) ) , Ok ( true ) ) ;
291291 assert_eq ! ( model. objects( ) . len( ) , 2 ) ;
292292 assert_eq ! ( model. morphisms( ) . len( ) , 1 ) ;
293- assert ! ( model. validate( ) . is_empty( ) ) ;
293+ assert_eq ! ( model. objects_with_type( ObType :: Basic ( "Entity" . into( ) ) ) , Ok ( vec![ Ob :: Basic ( x) ] ) ) ;
294+ assert_eq ! (
295+ model. morphisms_with_type( MorType :: Basic ( "Attr" . into( ) ) ) ,
296+ Ok ( vec![ Mor :: Basic ( a) ] )
297+ ) ;
298+ assert_eq ! ( model. validate( ) . 0 , JsResult :: Ok ( ( ) ) ) ;
294299
295300 let mut model = DblModel :: new ( & th) ;
296301 assert ! ( model
@@ -301,6 +306,9 @@ mod tests {
301306 cod: Some ( Ob :: Basic ( y) ) ,
302307 } )
303308 . is_ok( ) ) ;
304- assert_eq ! ( model. validate( ) . len( ) , 2 ) ;
309+ let JsResult :: Err ( errs) = model. validate ( ) . 0 else {
310+ panic ! ( "Model should not validate" )
311+ } ;
312+ assert_eq ! ( errs. len( ) , 2 ) ;
305313 }
306314}
0 commit comments