scir/
schema.rs

1//! Traits and definitions associated with schemas, or data formats
2//! used for storing SCIR libraries.
3
4use crate::Instance;
5use arcstr::ArcStr;
6use serde::{Deserialize, Serialize};
7use std::convert::Infallible;
8
9/// A data format for storing SCIR libraries.
10// TODO: Add method of validating primitive instances.
11pub trait Schema {
12    /// A primitive used for storing arbitrary data that is opaque to SCIR.
13    type Primitive: Primitive + Sized;
14}
15
16/// A primitive of a SCIR schema.
17pub trait Primitive {}
18
19impl<T> Primitive for T {}
20
21/// A schema that can be converted from another schema.
22pub trait FromSchema<S: Schema + ?Sized>: Schema {
23    /// The conversion error type.
24    type Error;
25
26    /// Converts a primitive of the other schema to a primitive of this schema.
27    fn convert_primitive(
28        primitive: <S as Schema>::Primitive,
29    ) -> Result<<Self as Schema>::Primitive, Self::Error>;
30
31    /// Converts an instance from the other schema to a new instance
32    /// based on its associated primitive.
33    fn convert_instance(
34        instance: &mut Instance,
35        primitive: &<S as Schema>::Primitive,
36    ) -> Result<(), Self::Error>;
37}
38
39impl<S: Schema + ?Sized> FromSchema<S> for S {
40    type Error = Infallible;
41
42    fn convert_primitive(
43        primitive: <S as Schema>::Primitive,
44    ) -> Result<<Self as Schema>::Primitive, Self::Error> {
45        Ok(primitive)
46    }
47
48    fn convert_instance(
49        _instance: &mut Instance,
50        _primitive: &<S as Schema>::Primitive,
51    ) -> Result<(), Self::Error> {
52        Ok(())
53    }
54}
55
56/// A schema with no primitives.
57pub struct NoSchema;
58
59/// An error converting to/from [`NoSchema`].
60#[derive(
61    Copy, Clone, Eq, PartialEq, Debug, Default, Hash, Serialize, Deserialize, thiserror::Error,
62)]
63#[error("attempted to convert a library containing primitives to/from `NoSchema`")]
64pub struct NoSchemaError;
65
66/// The primitive type of the [`NoSchema`] schema.
67///
68/// Cannot be instantiated as [`NoSchema`] cannot have
69/// primitives.
70#[derive(Clone, Serialize, Deserialize)]
71pub struct NoPrimitive(());
72
73impl Schema for NoSchema {
74    type Primitive = NoPrimitive;
75}
76
77/// A schema with arbitrary string primitives.
78pub struct StringSchema;
79
80impl Schema for StringSchema {
81    type Primitive = ArcStr;
82}
83
84impl FromSchema<NoSchema> for StringSchema {
85    type Error = NoSchemaError;
86
87    fn convert_primitive(
88        _primitive: <NoSchema as Schema>::Primitive,
89    ) -> Result<<Self as Schema>::Primitive, Self::Error> {
90        Err(NoSchemaError)
91    }
92    fn convert_instance(
93        _instance: &mut Instance,
94        _primitive: &<NoSchema as Schema>::Primitive,
95    ) -> Result<(), Self::Error> {
96        Err(NoSchemaError)
97    }
98}