xsd/lib.rs
1// This is free and unencumbered software released into the public domain.
2
3//! XML Schema (XSD) datatypes for Rust.
4//!
5//! # Features
6//!
7//! Disable defaults for `no_std`. Numeric values and datatype identifiers are
8//! available without this crate's `alloc` feature; `alloc` enables owned strings
9//! and allocation-dependent helpers. `datetime` (also exposed as `jiff`) enables
10//! date/time values without requiring `std`. `serde` and `borsh` imply `alloc`;
11//! `bson`, `oxrdf`, and `rudof` require `std`. Defaults enable `all` and `std`.
12//! Dependency features are forwarded explicitly; enabling serialization does
13//! not implicitly enable date/time support.
14//!
15//! ```rust
16//! use xsd::{Type, Value};
17//! use xsd::primitive::{Boolean, Decimal, Double, Duration, Float};
18//! # #[cfg(feature = "jiff")]
19//! use xsd::primitive::{Date, DateTime, Time};
20//! ```
21//!
22//! ## Sophia interoperability
23//!
24//! The `sophia` feature is currently an empty compatibility placeholder. It
25//! enables no dependencies, trait implementations, or conversion APIs in this
26//! crate, and does not enable `alloc` or `std`. In particular, enabling it does
27//! not make [`Value`] or [`PrimitiveValue`] implement Sophia term traits.
28//! Applications integrating with Sophia must provide their own term conversion,
29//! retaining RDF lexical forms and datatype identifiers outside parsed values.
30//!
31//! ## JSON-LD interoperability
32//!
33//! The `json-ld` feature is currently an empty compatibility placeholder. It
34//! enables no dependencies, JSON-LD processing, or conversion APIs, and does not
35//! enable `alloc`, `std`, or `serde`. Explicit JSON conversion methods on values
36//! require the separate `serde` feature. Those methods produce JSON values,
37//! not JSON-LD value objects carrying `@value` and `@type`; they do not provide
38//! JSON-LD expansion, compaction, or RDF datatype-preserving round trips.
39//!
40//! ## Rudof interoperability
41//!
42//! The `rudof` feature enables `std` (and thus `alloc`) and the optional
43//! `oxsdatatypes` dependency. It currently provides no dedicated Rudof or
44//! `oxsdatatypes` conversion API, trait implementations, or public re-exports.
45//! It also does not enable `datetime` or change which datatypes [`parse`]
46//! supports. Applications using `oxsdatatypes` directly must declare their own
47//! dependency and handle conversion and representation limits explicitly.
48//!
49//! ## Borsh interoperability
50//!
51//! The `borsh` feature enables `BorshSerialize` and `BorshDeserialize` for
52//! [`Type`], [`PrimitiveType`], [`DecimalType`], [`DecimalValue`], and
53//! [`TimezoneOffset`]. It also
54//! forwards Borsh support to the numeric backend and enables `alloc`, without
55//! requiring `std`.
56//! With `jiff` as well, `primitive::Date`, `primitive::Time`, and
57//! `primitive::DateTime` support versioned, validated type-local encodings
58//! documented on those types. `primitive::GMonth`, `primitive::GDay`,
59//! `primitive::GMonthDay`, and `primitive::GYearMonth` have
60//! versioned, validated encodings available without date/time features; see
61//! their migration notes.
62//!
63//! [`Value`] and [`PrimitiveValue`] do **not** implement Borsh serialization or
64//! deserialization, even with `borsh` enabled. Wrapping a supported numeric
65//! value in either enum does not make that wrapper serializable.
66//!
67//! The supported enums use structural binary encodings, not XSD lexical strings.
68//! Round trips preserve their variants and stored data; they cannot recover
69//! original lexical spelling that was discarded during parsing. This feature
70//! does not define a versioned, cross-release interchange format.
71
72#![cfg_attr(
73 feature = "borsh",
74 doc = r#"
75### Borsh examples
76
77Supported types round-trip through Borsh (requires `borsh`):
78
79```
80fn round_trip<T>(value: T)
81where
82 T: borsh::BorshSerialize + borsh::BorshDeserialize + PartialEq + core::fmt::Debug,
83{
84 let bytes = borsh::to_vec(&value).unwrap();
85 assert_eq!(borsh::from_slice::<T>(&bytes).unwrap(), value);
86}
87round_trip(xsd::DATE);
88round_trip(xsd::PrimitiveType::Date);
89round_trip(xsd::DecimalType::Int);
90round_trip(xsd::DecimalValue::Int(42));
91```
92
93The general value wrapper is intentionally outside this supported boundary:
94
95```compile_fail,E0277
96let value = xsd::Value::from(xsd::DecimalValue::Int(42));
97let bytes = borsh::to_vec(&value).unwrap();
98```
99
100The primitive wrapper likewise does not implement Borsh deserialization:
101
102```compile_fail,E0277
103let value = borsh::from_slice::<xsd::PrimitiveValue>(&[]).unwrap();
104```
105"#
106)]
107#![no_std]
108#![deny(unsafe_code)]
109#![cfg_attr(docsrs, feature(doc_cfg))]
110
111#[cfg(feature = "alloc")]
112extern crate alloc;
113
114/// The XSD namespace base URI (`http://www.w3.org/2001/XMLSchema#`).
115pub const BASE_URI: &'static str = "http://www.w3.org/2001/XMLSchema#";
116
117/// Rust types for representing values of XSD primitive datatypes.
118#[allow(unused_imports)]
119pub mod primitive {
120 mod boolean;
121 pub use boolean::*;
122
123 mod date;
124 pub use date::*;
125
126 mod datetime;
127 pub use datetime::*;
128
129 mod decimal;
130 pub use decimal::*;
131
132 mod double;
133 pub use double::*;
134
135 mod duration;
136 pub use duration::*;
137
138 mod float;
139 pub use float::*;
140
141 mod gday;
142 pub use gday::*;
143
144 mod gmonth;
145 pub use gmonth::*;
146
147 mod gmonthday;
148 pub use gmonthday::*;
149
150 mod gyear;
151 pub use gyear::*;
152
153 mod gyearmonth;
154 pub use gyearmonth::*;
155
156 mod string;
157 pub use string::*;
158
159 mod time;
160 pub use time::*;
161}
162
163/// Rust types for representing values of XSD derived datatypes.
164pub mod derived {
165 mod integer;
166 pub use integer::*;
167}
168
169mod decimal_type;
170pub use decimal_type::*;
171
172mod decimal_value;
173pub use decimal_value::*;
174
175mod parse;
176pub use parse::*;
177
178mod parse_calendar;
179pub use parse_calendar::*;
180
181mod parse_error;
182pub use parse_error::*;
183
184mod timezone_offset;
185pub use timezone_offset::*;
186
187mod primitive_type;
188pub use primitive_type::*;
189
190mod primitive_value;
191pub use primitive_value::*;
192
193mod r#type;
194pub use r#type::*;
195
196mod value;
197pub use value::*;
198
199#[doc = include_str!("../README.md")]
200#[cfg(all(doctest, feature = "alloc", feature = "jiff"))]
201pub struct ReadmeDoctests;