Skip to content
This repository was archived by the owner on Dec 11, 2024. It is now read-only.

Commit bfd8ae1

Browse files
authored
Merge pull request #17 from golemcloud/vigoo/type-constructors
Constructor functions for AnalysedType
2 parents 0184393 + a6465e5 commit bfd8ae1

File tree

4 files changed

+412
-610
lines changed

4 files changed

+412
-610
lines changed

src/analysis/mod.rs

Lines changed: 19 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -691,10 +691,10 @@ impl<Ast: AstCustomization + 'static> AnalysisContext<Ast> {
691691

692692
#[cfg(test)]
693693
mod tests {
694+
use crate::analysis::analysed_type::{f32, field, handle, record, result, str, u32, u64};
694695
use crate::analysis::{
695696
AnalysedFunction, AnalysedFunctionParameter, AnalysedFunctionResult, AnalysedResourceId,
696-
AnalysedResourceMode, AnalysedType, NameTypePair, TypeF32, TypeHandle, TypeRecord,
697-
TypeResult, TypeStr, TypeU32, TypeU64,
697+
AnalysedResourceMode,
698698
};
699699
use test_r::test;
700700

@@ -704,48 +704,28 @@ mod tests {
704704
name: "[constructor]cart".to_string(),
705705
parameters: vec![AnalysedFunctionParameter {
706706
name: "user-id".to_string(),
707-
typ: AnalysedType::Str(TypeStr),
707+
typ: str(),
708708
}],
709709
results: vec![AnalysedFunctionResult {
710710
name: None,
711-
typ: AnalysedType::Handle(TypeHandle {
712-
resource_id: AnalysedResourceId(0),
713-
mode: AnalysedResourceMode::Owned,
714-
}),
711+
typ: handle(AnalysedResourceId(0), AnalysedResourceMode::Owned),
715712
}],
716713
};
717714
let method = AnalysedFunction {
718715
name: "[method]cart.add-item".to_string(),
719716
parameters: vec![
720717
AnalysedFunctionParameter {
721718
name: "self".to_string(),
722-
typ: AnalysedType::Handle(TypeHandle {
723-
resource_id: AnalysedResourceId(0),
724-
mode: AnalysedResourceMode::Borrowed,
725-
}),
719+
typ: handle(AnalysedResourceId(0), AnalysedResourceMode::Borrowed),
726720
},
727721
AnalysedFunctionParameter {
728722
name: "item".to_string(),
729-
typ: AnalysedType::Record(TypeRecord {
730-
fields: vec![
731-
NameTypePair {
732-
name: "product-id".to_string(),
733-
typ: AnalysedType::Str(TypeStr),
734-
},
735-
NameTypePair {
736-
name: "name".to_string(),
737-
typ: AnalysedType::Str(TypeStr),
738-
},
739-
NameTypePair {
740-
name: "price".to_string(),
741-
typ: AnalysedType::F32(TypeF32),
742-
},
743-
NameTypePair {
744-
name: "quantity".to_string(),
745-
typ: AnalysedType::U32(TypeU32),
746-
},
747-
],
748-
}),
723+
typ: record(vec![
724+
field("product-id", str()),
725+
field("name", str()),
726+
field("price", f32()),
727+
field("quantity", u32()),
728+
]),
749729
},
750730
],
751731
results: vec![],
@@ -755,50 +735,30 @@ mod tests {
755735
parameters: vec![
756736
AnalysedFunctionParameter {
757737
name: "self".to_string(),
758-
typ: AnalysedType::Handle(TypeHandle {
759-
resource_id: AnalysedResourceId(0),
760-
mode: AnalysedResourceMode::Borrowed,
761-
}),
738+
typ: handle(AnalysedResourceId(0), AnalysedResourceMode::Borrowed),
762739
},
763740
AnalysedFunctionParameter {
764741
name: "that".to_string(),
765-
typ: AnalysedType::Handle(TypeHandle {
766-
resource_id: AnalysedResourceId(0),
767-
mode: AnalysedResourceMode::Borrowed,
768-
}),
742+
typ: handle(AnalysedResourceId(0), AnalysedResourceMode::Borrowed),
769743
},
770744
],
771745
results: vec![AnalysedFunctionResult {
772746
name: None,
773-
typ: AnalysedType::Handle(TypeHandle {
774-
resource_id: AnalysedResourceId(0),
775-
mode: AnalysedResourceMode::Owned,
776-
}),
747+
typ: handle(AnalysedResourceId(0), AnalysedResourceMode::Owned),
777748
}],
778749
};
779750
let fun = AnalysedFunction {
780751
name: "hash".to_string(),
781752
parameters: vec![AnalysedFunctionParameter {
782753
name: "path".to_string(),
783-
typ: AnalysedType::Str(TypeStr),
754+
typ: str(),
784755
}],
785756
results: vec![AnalysedFunctionResult {
786757
name: None,
787-
typ: AnalysedType::Result(TypeResult {
788-
ok: Some(Box::new(AnalysedType::Record(TypeRecord {
789-
fields: vec![
790-
NameTypePair {
791-
name: "lower".to_string(),
792-
typ: AnalysedType::U64(TypeU64),
793-
},
794-
NameTypePair {
795-
name: "upper".to_string(),
796-
typ: AnalysedType::U64(TypeU64),
797-
},
798-
],
799-
}))),
800-
err: Some(Box::new(AnalysedType::Str(TypeStr))),
801-
}),
758+
typ: result(
759+
record(vec![field("lower", u64()), field("upper", u64())]),
760+
str(),
761+
),
802762
}],
803763
};
804764

src/analysis/model.rs

Lines changed: 190 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,15 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use crate::analysis::analysed_type::{
16+
bool, chr, f32, f64, s16, s32, s64, s8, str, u16, u32, u64, u8,
17+
};
1518
use crate::analysis::AnalysisResult;
1619
use crate::component::{ComponentExternalKind, PrimitiveValueType};
1720

1821
#[derive(Debug, Clone, PartialEq, Hash, Eq)]
1922
#[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize))]
23+
#[cfg_attr(feature = "json", serde(tag = "type"))]
2024
#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
2125
#[cfg_attr(feature = "poem_openapi", derive(poem_openapi::Union))]
2226
#[cfg_attr(
@@ -281,6 +285,144 @@ pub enum AnalysedType {
281285
Handle(TypeHandle),
282286
}
283287

288+
pub mod analysed_type {
289+
use crate::analysis::*;
290+
291+
pub fn field(name: &str, typ: AnalysedType) -> NameTypePair {
292+
NameTypePair {
293+
name: name.to_string(),
294+
typ,
295+
}
296+
}
297+
298+
pub fn case(name: &str, typ: AnalysedType) -> NameOptionTypePair {
299+
NameOptionTypePair {
300+
name: name.to_string(),
301+
typ: Some(typ),
302+
}
303+
}
304+
305+
pub fn unit_case(name: &str) -> NameOptionTypePair {
306+
NameOptionTypePair {
307+
name: name.to_string(),
308+
typ: None,
309+
}
310+
}
311+
312+
pub fn bool() -> AnalysedType {
313+
AnalysedType::Bool(TypeBool)
314+
}
315+
316+
pub fn s8() -> AnalysedType {
317+
AnalysedType::S8(TypeS8)
318+
}
319+
320+
pub fn s16() -> AnalysedType {
321+
AnalysedType::S16(TypeS16)
322+
}
323+
324+
pub fn s32() -> AnalysedType {
325+
AnalysedType::S32(TypeS32)
326+
}
327+
328+
pub fn s64() -> AnalysedType {
329+
AnalysedType::S64(TypeS64)
330+
}
331+
332+
pub fn u8() -> AnalysedType {
333+
AnalysedType::U8(TypeU8)
334+
}
335+
336+
pub fn u16() -> AnalysedType {
337+
AnalysedType::U16(TypeU16)
338+
}
339+
340+
pub fn u32() -> AnalysedType {
341+
AnalysedType::U32(TypeU32)
342+
}
343+
344+
pub fn u64() -> AnalysedType {
345+
AnalysedType::U64(TypeU64)
346+
}
347+
348+
pub fn f32() -> AnalysedType {
349+
AnalysedType::F32(TypeF32)
350+
}
351+
352+
pub fn f64() -> AnalysedType {
353+
AnalysedType::F64(TypeF64)
354+
}
355+
356+
pub fn chr() -> AnalysedType {
357+
AnalysedType::Chr(TypeChr)
358+
}
359+
360+
pub fn str() -> AnalysedType {
361+
AnalysedType::Str(TypeStr)
362+
}
363+
364+
pub fn list(inner: AnalysedType) -> AnalysedType {
365+
AnalysedType::List(TypeList {
366+
inner: Box::new(inner),
367+
})
368+
}
369+
370+
pub fn option(inner: AnalysedType) -> AnalysedType {
371+
AnalysedType::Option(TypeOption {
372+
inner: Box::new(inner),
373+
})
374+
}
375+
376+
pub fn flags(names: &[&str]) -> AnalysedType {
377+
AnalysedType::Flags(TypeFlags {
378+
names: names.iter().map(|n| n.to_string()).collect(),
379+
})
380+
}
381+
382+
pub fn r#enum(cases: &[&str]) -> AnalysedType {
383+
AnalysedType::Enum(TypeEnum {
384+
cases: cases.iter().map(|n| n.to_string()).collect(),
385+
})
386+
}
387+
388+
pub fn tuple(items: Vec<AnalysedType>) -> AnalysedType {
389+
AnalysedType::Tuple(TypeTuple { items })
390+
}
391+
392+
pub fn result(ok: AnalysedType, err: AnalysedType) -> AnalysedType {
393+
AnalysedType::Result(TypeResult {
394+
ok: Some(Box::new(ok)),
395+
err: Some(Box::new(err)),
396+
})
397+
}
398+
399+
pub fn result_ok(ok: AnalysedType) -> AnalysedType {
400+
AnalysedType::Result(TypeResult {
401+
ok: Some(Box::new(ok)),
402+
err: None,
403+
})
404+
}
405+
406+
pub fn result_err(err: AnalysedType) -> AnalysedType {
407+
AnalysedType::Result(TypeResult {
408+
ok: None,
409+
err: Some(Box::new(err)),
410+
})
411+
}
412+
413+
pub fn record(fields: Vec<NameTypePair>) -> AnalysedType {
414+
AnalysedType::Record(TypeRecord { fields })
415+
}
416+
417+
pub fn variant(cases: Vec<NameOptionTypePair>) -> AnalysedType {
418+
AnalysedType::Variant(TypeVariant { cases })
419+
}
420+
421+
pub fn handle(resource_id: AnalysedResourceId, mode: AnalysedResourceMode) -> AnalysedType {
422+
AnalysedType::Handle(TypeHandle { resource_id, mode })
423+
}
424+
}
425+
284426
#[derive(Debug, Clone, PartialEq, Hash, Eq)]
285427
#[cfg_attr(feature = "json", derive(serde::Serialize, serde::Deserialize))]
286428
#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
@@ -299,19 +441,19 @@ pub struct AnalysedResourceId(pub u64);
299441
impl From<&PrimitiveValueType> for AnalysedType {
300442
fn from(value: &PrimitiveValueType) -> Self {
301443
match value {
302-
PrimitiveValueType::Bool => AnalysedType::Bool(TypeBool),
303-
PrimitiveValueType::S8 => AnalysedType::S8(TypeS8),
304-
PrimitiveValueType::U8 => AnalysedType::U8(TypeU8),
305-
PrimitiveValueType::S16 => AnalysedType::S16(TypeS16),
306-
PrimitiveValueType::U16 => AnalysedType::U16(TypeU16),
307-
PrimitiveValueType::S32 => AnalysedType::S32(TypeS32),
308-
PrimitiveValueType::U32 => AnalysedType::U32(TypeU32),
309-
PrimitiveValueType::S64 => AnalysedType::S64(TypeS64),
310-
PrimitiveValueType::U64 => AnalysedType::U64(TypeU64),
311-
PrimitiveValueType::F32 => AnalysedType::F32(TypeF32),
312-
PrimitiveValueType::F64 => AnalysedType::F64(TypeF64),
313-
PrimitiveValueType::Chr => AnalysedType::Chr(TypeChr),
314-
PrimitiveValueType::Str => AnalysedType::Str(TypeStr),
444+
PrimitiveValueType::Bool => bool(),
445+
PrimitiveValueType::S8 => s8(),
446+
PrimitiveValueType::U8 => u8(),
447+
PrimitiveValueType::S16 => s16(),
448+
PrimitiveValueType::U16 => u16(),
449+
PrimitiveValueType::S32 => s32(),
450+
PrimitiveValueType::U32 => u32(),
451+
PrimitiveValueType::S64 => s64(),
452+
PrimitiveValueType::U64 => u64(),
453+
PrimitiveValueType::F32 => f32(),
454+
PrimitiveValueType::F64 => f64(),
455+
PrimitiveValueType::Chr => chr(),
456+
PrimitiveValueType::Str => str(),
315457
}
316458
}
317459
}
@@ -381,3 +523,38 @@ impl AnalysisFailure {
381523
}
382524
}
383525
}
526+
527+
#[cfg(test)]
528+
mod tests {
529+
use crate::analysis::analysed_type::{bool, list, str};
530+
use crate::analysis::{
531+
AnalysedExport, AnalysedFunction, AnalysedFunctionParameter, AnalysedFunctionResult,
532+
AnalysedInstance,
533+
};
534+
use poem_openapi::types::ToJSON;
535+
use pretty_assertions::assert_eq;
536+
537+
#[cfg(feature = "poem_openapi")]
538+
#[cfg(feature = "json")]
539+
#[test]
540+
fn analysed_export_poem_and_serde_are_compatible() {
541+
let export1 = AnalysedExport::Instance(AnalysedInstance {
542+
name: "inst1".to_string(),
543+
functions: vec![AnalysedFunction {
544+
name: "func1".to_string(),
545+
parameters: vec![AnalysedFunctionParameter {
546+
name: "param1".to_string(),
547+
typ: bool(),
548+
}],
549+
results: vec![AnalysedFunctionResult {
550+
name: None,
551+
typ: list(str()),
552+
}],
553+
}],
554+
});
555+
let poem_serialized = export1.to_json_string();
556+
let serde_deserialized: AnalysedExport = serde_json::from_str(&poem_serialized).unwrap();
557+
558+
assert_eq!(export1, serde_deserialized);
559+
}
560+
}

0 commit comments

Comments
 (0)