Skip to content

Commit

Permalink
Get cycles working.
Browse files Browse the repository at this point in the history
  • Loading branch information
milesj committed Apr 25, 2024
1 parent 5ecba30 commit 0c38898
Show file tree
Hide file tree
Showing 15 changed files with 332 additions and 116 deletions.
40 changes: 24 additions & 16 deletions crates/types/src/arrays.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::schema_type::SchemaType;
use crate::{Schema, SchemaBuilder, Schematic};
use std::collections::{BTreeSet, HashSet};

#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ArrayType {
pub contains: Option<bool>,
pub items_type: Box<SchemaType>,
Expand All @@ -23,31 +23,24 @@ impl ArrayType {
}
}

macro_rules! impl_list {
($type:ident) => {
impl<T: Schematic> Schematic for $type<T> {
fn generate_schema(mut schema: SchemaBuilder) -> Schema {
schema.array(ArrayType::new(schema.infer::<T>()));
schema.build()
}
}
};
impl<T: Schematic> Schematic for Vec<T> {
fn generate_schema(mut schema: SchemaBuilder) -> Schema {
schema.array(ArrayType::new(schema.infer_type::<T>()));
schema.build()
}
}

impl_list!(Vec);
impl_list!(BTreeSet);

impl<T: Schematic> Schematic for &[T] {
fn generate_schema(mut schema: SchemaBuilder) -> Schema {
schema.array(ArrayType::new(schema.infer::<T>()));
schema.array(ArrayType::new(schema.infer_type::<T>()));
schema.build()
}
}

impl<T: Schematic, const N: usize> Schematic for [T; N] {
fn generate_schema(mut schema: SchemaBuilder) -> Schema {
schema.array(ArrayType {
items_type: Box::new(schema.infer::<T>()),
items_type: Box::new(schema.infer_type::<T>()),
max_length: Some(N),
min_length: Some(N),
..ArrayType::default()
Expand All @@ -58,7 +51,22 @@ impl<T: Schematic, const N: usize> Schematic for [T; N] {

impl<T: Schematic, S> Schematic for HashSet<T, S> {
fn generate_schema(mut schema: SchemaBuilder) -> Schema {
schema.array(ArrayType::new(schema.infer::<T>()));
schema.array(ArrayType {
items_type: Box::new(schema.infer_type::<T>()),
unique: Some(true),
..ArrayType::default()
});
schema.build()
}
}

impl<T: Schematic> Schematic for BTreeSet<T> {
fn generate_schema(mut schema: SchemaBuilder) -> Schema {
schema.array(ArrayType {
items_type: Box::new(schema.infer_type::<T>()),
unique: Some(true),
..ArrayType::default()
});
schema.build()
}
}
2 changes: 1 addition & 1 deletion crates/types/src/bools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::schema::Schema;
use crate::schema_builder::SchemaBuilder;
use crate::Schematic;

#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct BooleanType {
pub default: Option<LiteralValue>,
}
Expand Down
2 changes: 1 addition & 1 deletion crates/types/src/enums.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::literals::LiteralValue;
use crate::schema::SchemaField;

#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct EnumType {
pub default_index: Option<usize>,
pub values: Vec<LiteralValue>,
Expand Down
46 changes: 25 additions & 21 deletions crates/types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ pub use unions::*;

/// Defines a schema that represents the shape of the implementing type.
pub trait Schematic {
fn schema_id() -> Option<String> {
/// Define a name for this schema type. Names are required for non-primitive values
/// as a means to link references, and avoid cycles.
fn schema_name() -> Option<String> {
None
}

Expand All @@ -49,26 +51,28 @@ impl Schematic for () {
}
}

// impl<T: Schematic> Schematic for &T {
// fn generate_schema() -> SchemaType {
// T::generate_schema()
// }
// }
impl<T: Schematic> Schematic for &T {
fn generate_schema(schema: SchemaBuilder) -> Schema {
T::generate_schema(schema)
}
}

// impl<T: Schematic> Schematic for &mut T {
// fn generate_schema() -> SchemaType {
// T::generate_schema()
// }
// }
impl<T: Schematic> Schematic for &mut T {
fn generate_schema(schema: SchemaBuilder) -> Schema {
T::generate_schema(schema)
}
}

// impl<T: Schematic> Schematic for Box<T> {
// fn generate_schema() -> SchemaType {
// T::generate_schema()
// }
// }
impl<T: Schematic> Schematic for Box<T> {
fn generate_schema(schema: SchemaBuilder) -> Schema {
T::generate_schema(schema)
}
}

// impl<T: Schematic> Schematic for Option<T> {
// fn generate_schema() -> SchemaType {
// SchemaType::nullable(T::generate_schema())
// }
// }
impl<T: Schematic> Schematic for Option<T> {
fn generate_schema(mut schema: SchemaBuilder) -> Schema {
schema.custom(schema.infer_type::<T>());
schema.nullable();
schema.build()
}
}
4 changes: 2 additions & 2 deletions crates/types/src/literals.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq)]
pub enum LiteralValue {
Bool(bool),
F32(f32),
Expand All @@ -8,7 +8,7 @@ pub enum LiteralValue {
String(String),
}

#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct LiteralType {
pub format: Option<String>,
pub value: Option<LiteralValue>,
Expand Down
8 changes: 4 additions & 4 deletions crates/types/src/numbers.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::literals::LiteralValue;
use crate::{Schema, SchemaBuilder, Schematic};

#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, PartialEq)]
pub enum IntegerKind {
Isize,
I8,
Expand All @@ -27,7 +27,7 @@ impl IntegerKind {
}
}

#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct IntegerType {
pub default: Option<LiteralValue>,
pub enum_values: Option<Vec<isize>>,
Expand Down Expand Up @@ -97,14 +97,14 @@ impl_int!(i32, IntegerKind::I32);
impl_int!(i64, IntegerKind::I64);
impl_int!(i128, IntegerKind::I128);

#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, PartialEq)]
pub enum FloatKind {
#[default]
F32,
F64,
}

#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct FloatType {
pub default: Option<LiteralValue>,
pub enum_values: Option<Vec<f64>>,
Expand Down
12 changes: 9 additions & 3 deletions crates/types/src/objects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::schema_type::SchemaType;
use crate::{Schema, SchemaBuilder, Schematic};
use std::collections::{BTreeMap, HashMap};

#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct ObjectType {
pub key_type: Box<SchemaType>,
pub max_length: Option<usize>,
Expand All @@ -24,14 +24,20 @@ impl ObjectType {

impl<K: Schematic, V: Schematic> Schematic for BTreeMap<K, V> {
fn generate_schema(mut schema: SchemaBuilder) -> Schema {
schema.object(ObjectType::new(schema.infer::<K>(), schema.infer::<V>()));
schema.object(ObjectType::new(
schema.infer_type::<K>(),
schema.infer_type::<V>(),
));
schema.build()
}
}

impl<K: Schematic, V: Schematic, S> Schematic for HashMap<K, V, S> {
fn generate_schema(mut schema: SchemaBuilder) -> Schema {
schema.object(ObjectType::new(schema.infer::<K>(), schema.infer::<V>()));
schema.object(ObjectType::new(
schema.infer_type::<K>(),
schema.infer_type::<V>(),
));
schema.build()
}
}
20 changes: 16 additions & 4 deletions crates/types/src/schema.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
use crate::schema_type::SchemaType;

#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Schema {
pub description: Option<String>,
pub name: Option<String>,
pub type_of: SchemaType,
}

/// Represents a field within a schema struct, or a variant within a schema enum/union.
#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct SchemaField {
pub name: String,
pub description: Option<String>,
pub type_of: Box<SchemaType>,
pub type_name: Option<String>,
pub deprecated: Option<String>,
pub env_var: Option<String>,
pub hidden: bool,
Expand All @@ -23,12 +24,23 @@ pub struct SchemaField {
}

impl SchemaField {
/// Create a new field with the provided name and type.
pub fn new(name: &str, type_of: SchemaType) -> SchemaField {
/// Create a new field from a [`SchemaType`].
pub fn from_type(name: &str, type_of: SchemaType) -> SchemaField {
SchemaField {
name: name.to_owned(),
type_of: Box::new(type_of),
..SchemaField::default()
}
}

/// Create a new field from a [`Schema`].
pub fn from_schema(name: &str, schema: Schema) -> SchemaField {
SchemaField {
name: name.to_owned(),
description: schema.description,
type_of: Box::new(schema.type_of),
type_name: schema.name,
..SchemaField::default()
}
}
}
Loading

0 comments on commit 0c38898

Please sign in to comment.