icydb_schema/build/
mod.rs1use crate::{Error, ThisError, node::Schema, prelude::*, validate::validate_schema};
2use std::sync::{LazyLock, OnceLock, RwLock, RwLockReadGuard, RwLockWriteGuard};
3
4#[derive(Debug, ThisError)]
12pub enum BuildError {
13 #[error("validation failed: {0}")]
14 Validation(ErrorTree),
15}
16
17static SCHEMA: LazyLock<RwLock<Schema>> = LazyLock::new(|| RwLock::new(Schema::new()));
19
20static SCHEMA_VALIDATED: OnceLock<bool> = OnceLock::new();
21
22pub fn schema_write() -> RwLockWriteGuard<'static, Schema> {
24 SCHEMA
25 .write()
26 .expect("schema RwLock poisoned while acquiring write lock")
27}
28
29pub(crate) fn schema_read() -> RwLockReadGuard<'static, Schema> {
31 SCHEMA
32 .read()
33 .expect("schema RwLock poisoned while acquiring read lock")
34}
35
36pub fn get_schema() -> Result<RwLockReadGuard<'static, Schema>, Error> {
38 let schema = schema_read();
39 validate(&schema).map_err(BuildError::Validation)?;
40
41 Ok(schema)
42}
43
44fn validate(schema: &Schema) -> Result<(), ErrorTree> {
46 if *SCHEMA_VALIDATED.get_or_init(|| false) {
47 return Ok(());
48 }
49
50 validate_schema(schema)?;
51
52 SCHEMA_VALIDATED.set(true).ok();
53
54 Ok(())
55}