diff --git a/specta-util/Cargo.toml b/specta-util/Cargo.toml index 12e61f0..f742f22 100644 --- a/specta-util/Cargo.toml +++ b/specta-util/Cargo.toml @@ -31,3 +31,4 @@ specta = { version = "=2.0.0-rc.16", path = "../specta" } specta-macros = { version = "=2.0.0-rc.16", path = "../specta-macros", default-features = false, optional = true } ctor = { version = "0.2.8", default-features = false, optional = true } serde = "1.0.204" # TODO: Can we remove this or at least make it optional behind the `serde` flag +serde_json = "1" # TODO: Remove this or make it optional diff --git a/specta-util/src/type_collection.rs b/specta-util/src/type_collection.rs index 69e9264..bd7876d 100644 --- a/specta-util/src/type_collection.rs +++ b/specta-util/src/type_collection.rs @@ -1,17 +1,24 @@ -use std::{borrow::Borrow, collections::HashMap, path::Path}; +use std::{ + borrow::{Borrow, Cow}, + collections::HashMap, + path::Path, +}; use specta::{Language, NamedDataType, NamedType, SpectaID, TypeMap}; /// Define a set of types which can be exported together #[derive(Debug, Clone, PartialEq, Eq)] pub struct TypeCollection { + // TODO: Make into a single `Vec` to maintain global ordering? types: HashMap NamedDataType>, + constants: HashMap, serde_json::Value>, // TODO: Can we make this format agnostic? } impl Default for TypeCollection { fn default() -> Self { Self { - types: HashMap::new(), + types: Default::default(), + constants: Default::default(), } } } @@ -19,15 +26,31 @@ impl Default for TypeCollection { impl TypeCollection { #[allow(unused)] pub(crate) fn from_raw(types: HashMap NamedDataType>) -> Self { - Self { types } + Self { + types, + constants: Default::default(), + } } + // TODO: Maybe register framework info for default header + /// Join another type collection into this one. pub fn extend(&mut self, collection: impl Borrow) -> &mut Self { - self.types.extend(collection.borrow().types.iter()); + let collection = collection.borrow(); + self.types.extend(collection.types.iter()); + self.constants.extend( + collection + .constants + .iter() + .map(|(k, v)| (k.clone(), v.clone())), + ); self } + // TODO: Should you be allowed to merge in a `TypeMap`??? + + // TODO: Should you be able to output a type_map from our internal registry + /// Register a type with the collection. pub fn register(&mut self) -> &mut Self { self.types @@ -35,6 +58,18 @@ impl TypeCollection { self } + /// TODO + // #[cfg(feature = "serde")] // TODO + pub fn constant( + &mut self, + name: impl Into>, + value: T, + ) -> &mut Self { + self.constants + .insert(name.into(), serde_json::to_value(value).unwrap()); // TODO: Error handling + self + } + /// Export all the types in the collection into the given type map. pub fn collect(&self, mut type_map: &mut TypeMap) { for (sid, export) in self.types.iter() { @@ -47,9 +82,10 @@ impl TypeCollection { pub fn export(&self, language: L) -> Result { let mut type_map = TypeMap::default(); self.collect(&mut type_map); - language.export(type_map) + language.export(type_map) // TODO: &self.constants } + // TODO: Maybe we could put `path` on `Language` and remove this? /// TODO pub fn export_to( &self,