1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
//! # bo4e
//!
//! Rust implementation of the **BO4E** energy-market data standard.
//!
//! ## Feature gates
//!
//! | Feature | Default | Description |
//! |--------------|---------|----------------------------------------------------------------|
//! | `serde` | ✓ | Serde derives + extension-data map (opt out with `default-features = false`) |
//! | `json` | | `serde_json` helpers (`to_json_*`, `from_json_*`) |
//! | `simd-json` | | SIMD parser backend for `from_json_*` (workload-dependent) |
//! | `time` | | `time` crate for timestamps |
//! | `decimal` | | `rust_decimal::Decimal` for amounts/prices |
//! | `builder` | | `typed-builder` derives with `setter(into)` — accepts both `T` and `Option<T>` |
//! | `validate` | | `garde` validation |
//! | `schemars` | | JSON Schema generation |
//! | `sqlx` | | `sqlx` type integrations |
//! | `utoipa` | | `utoipa` OpenAPI integrations |
//! | `strum` | | Enum iteration and string conversion |
//! | `versioned` | | Expose versioned schema modules (`v202501`) |
//! | `tracing` | | Structured diagnostics via the `tracing` crate |
//! | `metrics` | | Optional export hooks via the `metrics` crate |
//!
//! ## `serde` is enabled by default
//!
//! The `serde` feature is included in `default = ["serde"]`. Targets that only
//! need the type definitions for in-memory processing can opt out:
//! ```toml
//! rubo4e = { version = "...", default-features = false, features = ["versioned"] }
//! ```
//!
//! ## Why generated structs do not implement `Eq`
//!
//! Generated BO and COM structs derive `PartialEq` but **not `Eq`**. The
//! `_additional` extension-data field (present when the `json` feature is active)
//! has type `LimitedExtensionMap` whose inner map contains `serde_json::Value`.
//! `serde_json::Value` does not implement `Eq` because it wraps `f64` (JSON
//! numbers), and `f64` is not `Eq` (`NaN ≠ NaN`). This is intentional and
//! correct behaviour.
//!
//! For content-addressed equality comparisons, use `to_json_canonical()`
//! (from `Bo4eJsonExt` in the `json` module) which produces a deterministic
//! byte string that can be compared with `==`.
/// Error types returned by identifier construction.
/// JSON serialization helpers: `json::Bo4eJsonExt` with `to_json_german()`,
/// `to_json_snake_case()`, and `to_json_canonical()`.
/// Always-available re-export of `json::extension::LimitedExtensionMap`.
///
/// When the `json` feature is **active** this is the real DoS-hardened extension
/// map. When `json` is **inactive** it degrades to a zero-sized stub that is
/// `Debug + Clone + Default + PartialEq` but carries no data. All generated
/// BO/COM structs use `crate::LimitedExtensionMap` as their `_additional` field
/// type so that the field can be declared once without a `#[cfg]` branch.
pub use LimitedExtensionMap;
/// Zero-sized stub used when the `json` feature is disabled.
///
/// See the `json`-feature variant for the full description.
;
/// Cross-field business-rule validators for BO4E types (requires `validate` + `versioned`).
/// Also exports `Validated<T>` which only requires `validate`.
/// Schema helper functions used by generated schemars attributes.
///
/// These provide `"format": "date-time"` annotations for `time::OffsetDateTime` fields,
/// which schemars 1.x does not emit automatically.
// Versioned schema modules — emitted by the generator; gated behind `versioned`.
// Run `just generate` to populate or refresh these modules.
/// BO4E schema v202501 types (latest stable release).
/// Alias to the latest stable BO4E schema version (`v202501` today).
///
/// Use `rubo4e::current` when you always want the newest stable types and do
/// not need to pin to a specific version. Pin to a concrete module
/// (`rubo4e::v202501`) if you need version-stability across crate updates.
///
/// Updated with each new minor/major schema release.
pub use v202501 as current;
/// Marker trait implemented by every generated BO4E business object (Geschäftsobjekt).
///
/// Provides runtime access to the BO type discriminant and the schema version that
/// was used to generate this type. COM types and enums do NOT implement this trait.
///
/// # Sealed trait
///
/// `Bo4eObject` is sealed — it cannot be implemented by types outside this crate.
/// This allows the library to add new methods in future releases without breaking
/// downstream code that merely *uses* the trait.
///
/// # Design note — associated type over bare return type
///
/// `bo_type()` returns `Self::BoTyp` (an associated type) so that the single trait
/// definition in `src/lib.rs` can serve all schema versions while keeping each
/// version's `BoTyp` enum strongly typed. For `dyn` usage, bind the associated type:
///
/// ```rust,ignore
/// use rubo4e::v202501::BoTyp;
/// let objects: Vec<Box<dyn rubo4e::Bo4eObject<BoTyp = BoTyp>>> = vec![
/// Box::new(Vertrag::default()),
/// Box::new(Marktlokation::default()),
/// ];
/// for obj in &objects {
/// println!("{:?} schema={}", obj.bo_type(), obj.schema_version());
/// }
/// ```
///
/// # Example
/// ```rust,ignore
/// use rubo4e::prelude::*;
/// let v = Vertrag::default();
/// assert_eq!(v.bo_type(), BoTyp::Vertrag);
/// assert_eq!(v.schema_version(), "v202501.0.0");
/// ```
/// Re-exports the most commonly used types.
///
/// `use rubo4e::prelude::*;` gives you all identifiers, the `Bo4eJsonExt` trait
/// (when `json` feature is active), and the [`Bo4eObject`] marker trait (when
/// `versioned` feature is active).