Skip to main content

qubit_metadata/
lib.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! # qubit-metadata
10//!
11//! A general-purpose, type-safe, extensible metadata model for Rust.
12//!
13//! This crate provides a [`Metadata`] type — a structured key-value store
14//! designed for any domain that needs to attach typed annotations to its data
15//! models. It is not a plain `HashMap` — it is a structured extensibility point
16//! with type-safe access, [`qubit_value::Value`] backing, and first-class
17//! `serde` support.
18//!
19//! ## Design Goals
20//!
21//! - **Type Safety**: Typed get/set API backed by [`qubit_value::Value`]
22//! - **Generality**: No domain-specific assumptions — usable in any Rust project
23//! - **Schema Support**: Optional [`MetadataSchema`] validation for metadata and filters
24//! - **Serialization**: First-class `serde` support for JSON interchange
25//! - **Filtering**: [`MetadataFilter`] for composable query conditions
26//!
27//! ## Features
28//!
29//! - Core type: [`Metadata`] — an ordered key-value store with typed accessors
30//! - Schema type: [`MetadataSchema`] — field definitions based on [`qubit_common::DataType`]
31//! - Filter type: [`MetadataFilter`] — composable filter expressions for metadata queries
32//! - Condition type: [`Condition`] — individual comparison predicates
33//! - Error type: [`MetadataError`] — explicit failure reporting for `try_*` APIs
34//!
35//! ## Example
36//!
37//! ```rust
38//! use qubit_metadata::{Metadata, MetadataFilter};
39//!
40//! let meta = Metadata::new()
41//!     .with("author", "alice")
42//!     .with("priority", 3_i64);
43//!
44//! // Convenience API: missing key and type mismatch both collapse to None.
45//! let author: Option<String> = meta.get("author");
46//! assert_eq!(author.as_deref(), Some("alice"));
47//!
48//! // Explicit API: preserve failure reasons for diagnostics.
49//! let priority = meta.try_get::<i64>("priority").unwrap();
50//! assert_eq!(priority, 3);
51//!
52//! let filter = MetadataFilter::builder()
53//!     .eq("author", "alice")
54//!     .and_ge("priority", 1_i64)
55//!     .build()
56//!     .unwrap();
57//! assert!(filter.matches(&meta));
58//! ```
59//!
60//! ## Author
61//!
62//! Haixing Hu
63
64#![deny(missing_docs)]
65
66mod filter;
67mod metadata;
68mod metadata_error;
69mod metadata_result;
70mod schema;
71
72pub use filter::Condition;
73pub use filter::FilterMatchOptions;
74pub use filter::MetadataFilter;
75pub use filter::MetadataFilterBuilder;
76pub use filter::MissingKeyPolicy;
77pub use filter::NumberComparisonPolicy;
78pub use metadata::Metadata;
79pub use metadata_error::MetadataError;
80pub use metadata_result::MetadataResult;
81pub use schema::MetadataField;
82pub use schema::MetadataSchema;
83pub use schema::MetadataSchemaBuilder;
84pub use schema::UnknownFieldPolicy;