sheetport_spec/lib.rs
1//! SheetPort manifest specification types and helpers.
2//!
3//! This crate defines the canonical data model for Formualizer I/O (FIO) manifests,
4//! provides serde serialization/deserialization, JSON Schema metadata, and
5//! validation helpers for authoring manifests that treat spreadsheets as pure
6//! input/output functions.
7
8mod manifest;
9mod validation;
10
11pub use manifest::*;
12pub use validation::{ManifestIssue, ValidationError};
13
14/// Version of this reference implementation crate.
15///
16/// This is expected to track the manifest `spec_version` for the supported spec.
17pub const CRATE_VERSION: &str = env!("CARGO_PKG_VERSION");
18
19/// Returns the canonical JSON Schema (Draft 2019-09) for the current manifest version.
20pub fn schema_json() -> &'static str {
21 include_str!("../schema/fio-0.3.json")
22}
23
24/// Generate the JSON Schema for [`Manifest`] using schemars at runtime.
25///
26/// This is primarily used for verifying that the bundled schema file is up to date.
27pub fn generate_schema_json_pretty() -> String {
28 use schemars::generate::SchemaSettings;
29
30 let settings = SchemaSettings::draft2019_09();
31 let generator = settings.into_generator();
32 let root = generator.into_root_schema_for::<Manifest>();
33 serde_json::to_string_pretty(&root).expect("RootSchema should serialize to JSON")
34}
35
36/// Generate the JSON Schema as a `serde_json::Value`.
37pub fn generate_schema_value() -> serde_json::Value {
38 serde_json::from_str(&generate_schema_json_pretty()).expect("RootSchema JSON should be valid")
39}
40
41/// Load a manifest from any reader implementing [`std::io::Read`].
42///
43/// # Examples
44/// ```
45/// # use sheetport_spec::Manifest;
46/// # let yaml = br#"spec: fio
47/// # spec_version: "0.3.0"
48/// # manifest: { id: sample, name: Sample }
49/// # ports: []
50/// # "#;
51/// let manifest = Manifest::from_yaml_reader(&yaml[..]).unwrap();
52/// assert_eq!(manifest.manifest.name, "Sample");
53/// ```
54pub fn load_manifest_from_reader<R: std::io::Read>(
55 reader: R,
56) -> Result<Manifest, serde_yaml::Error> {
57 Manifest::from_yaml_reader(reader)
58}
59
60/// Load a manifest from a YAML string slice.
61pub fn load_manifest_from_str(yaml: &str) -> Result<Manifest, serde_yaml::Error> {
62 Manifest::from_yaml_str(yaml)
63}
64
65/// Serialize a manifest back to YAML, in a stable order.
66pub fn manifest_to_yaml(manifest: &Manifest) -> Result<String, serde_yaml::Error> {
67 manifest.to_yaml()
68}