Skip to main content

faucet_cli/catalog/
spec.rs

1//! Serde config types for the top-level `catalog:` block (#279).
2
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6fn default_sample_records() -> usize {
7    100
8}
9
10/// The top-level `catalog:` block: opts a `faucet run` / `schedule` /
11/// `replicate` pipeline into recording the Data Movement Catalog after every
12/// successful root invocation. `faucet serve` records into its `--history`
13/// backend automatically — this block is for the non-serve runtimes (and for
14/// `faucet catalog`, which reads the same store).
15#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
16#[serde(deny_unknown_fields)]
17pub struct CatalogSpec {
18    /// Where the catalog is stored: `sqlite:<path>` (e.g.
19    /// `sqlite:./faucet-catalog.db`), a `postgres://…` URL, or `memory`
20    /// (process-lifetime only — useful for tests). SQL backends require the
21    /// matching `serve-history-sqlite` / `serve-history-postgres` build
22    /// feature. Point `faucet serve --history` at the same URL to browse the
23    /// accumulated catalog in the control plane + web console.
24    pub url: String,
25
26    /// How many records to sample per run for schema inference (per side).
27    /// The sample bounds memory; the schema timeline only ever stores the
28    /// inferred schema, never the records.
29    #[serde(default = "default_sample_records")]
30    pub sample_records: usize,
31}
32
33#[cfg(test)]
34mod tests {
35    use super::*;
36
37    #[test]
38    fn parses_minimal_block_with_defaults() {
39        let spec: CatalogSpec = serde_yaml::from_str("url: sqlite:./cat.db").unwrap();
40        assert_eq!(spec.url, "sqlite:./cat.db");
41        assert_eq!(spec.sample_records, 100);
42    }
43
44    #[test]
45    fn rejects_unknown_fields() {
46        let err = serde_yaml::from_str::<CatalogSpec>("url: memory\nnope: 1").unwrap_err();
47        assert!(err.to_string().contains("nope"));
48    }
49
50    #[test]
51    fn schema_generates() {
52        let schema = schemars::schema_for!(CatalogSpec);
53        let v = serde_json::to_value(&schema).unwrap();
54        assert!(v["properties"]["url"].is_object());
55    }
56}