use std::collections::HashMap; use schemars::{schema::RootSchema, schema_for, JsonSchema}; use serde::Serialize; #[derive(Serialize, JsonSchema, Debug, PartialEq)] pub struct Variable(pub u32); macro_rules! impl_content { ($($name:ident { $($arg:ident: $ty:ty,)* },)*) => { #[derive(Serialize, JsonSchema, Debug)] #[serde(tag = "type")] pub enum Content { $( $name { $($arg: $ty),* }, )* } impl Content { $( #[allow(non_snake_case)] pub fn $name($($arg: $ty),*) -> Self { Self::$name { $($arg),* } } )* } }; } impl_content! { Flex { name: Option, }, Rigid { name: String, }, FlexAble { name: Option, abilities: Vec, }, RigidAble { name: String, abilities: Vec, }, Recursive { name: Option, structure: Variable, }, LambdaSet { solved: Vec, unspecialized: Vec, recursion_var: Option, ambient_function: Variable, }, ErasedLambda {}, Alias { name: Symbol, variables: AliasTypeVariables, real_variable: Variable, kind: AliasKind, }, Apply { symbol: Symbol, variables: Vec, }, Function { arguments: Vec, lambda_type: Variable, ret: Variable, fx: Variable, }, Record { fields: HashMap, extension: Variable, }, Tuple { elements: HashMap, extension: Variable, }, TagUnion { tags: HashMap>, extension: TagUnionExtension, }, FunctionOrTagUnion { functions: Vec, tags: Vec, extension: TagUnionExtension, }, RecursiveTagUnion { recursion_var: Variable, tags: HashMap>, extension: TagUnionExtension, }, EmptyRecord {}, EmptyTagUnion {}, EffectfulFunc {}, RangedNumber { range: NumericRange, }, Pure {}, Effectful {}, Error {}, } #[derive(Serialize, JsonSchema, Debug)] pub struct ClosureType { pub function: Symbol, pub environment: Vec, } #[derive(Serialize, JsonSchema, Debug)] pub struct UnspecializedClosureType { pub specialization: Variable, pub ability_member: Symbol, pub lambda_set_region: u8, } #[derive(Serialize, JsonSchema, Debug)] #[serde(tag = "type")] pub enum AliasKind { Structural, Opaque, } #[derive(Serialize, JsonSchema, Debug)] pub struct AliasTypeVariables { pub type_variables: Vec, pub lambda_set_variables: Vec, pub infer_ext_in_output_position_variables: Vec, } #[derive(Serialize, JsonSchema, Debug)] pub struct RecordField { pub kind: RecordFieldKind, pub field_type: Variable, } #[derive(Serialize, JsonSchema, Debug)] #[serde(tag = "type")] pub enum RecordFieldKind { Demanded, Required { rigid: bool }, Optional { rigid: bool }, } #[derive(Serialize, JsonSchema, Debug)] #[serde(tag = "type", content = "variable")] pub enum TagUnionExtension { Openness(Variable), Any(Variable), } #[derive(Serialize, JsonSchema, Debug)] pub struct NumericRange { pub kind: NumericRangeKind, pub signed: bool, pub min_width: u32, } #[derive(Serialize, JsonSchema, Debug)] #[serde(tag = "type")] pub enum NumericRangeKind { Int, AnyNum, } #[derive(Serialize, JsonSchema, Debug)] pub struct Rank(pub u32); #[derive(Serialize, JsonSchema, Debug)] pub struct Symbol( // TODO: should this be module ID + symbol? pub String, ); #[derive(Serialize, JsonSchema, Debug)] #[serde(tag = "type")] pub enum UnificationMode { Eq, Present, LambdaSetSpecialization, } #[derive(Serialize, JsonSchema, Debug)] #[serde(tag = "type")] pub enum Event { Unification { left: Variable, right: Variable, mode: UnificationMode, success: Option, subevents: Vec, }, VariableUnified { from: Variable, to: Variable, }, VariableSetDescriptor { variable: Variable, rank: Option, content: Option, }, } #[derive(Serialize, JsonSchema, Debug)] pub struct AllEvents(pub Vec); impl AllEvents { pub fn schema() -> RootSchema { schema_for!(AllEvents) } pub fn write(&self, writer: impl std::io::Write) -> Result<(), serde_json::Error> { serde_json::to_writer(writer, self) } }