Skip to main content

rskit_dataset/
schema.rs

1//! Schema validation delegated to `rskit-schema`.
2
3use rskit_errors::{AppError, AppResult, ErrorCode};
4
5/// Compiled dataset record schema.
6pub struct DatasetSchema {
7    compiled: rskit_schema::CompiledSchema,
8}
9
10impl DatasetSchema {
11    /// Compile a JSON Schema for repeated record validation.
12    pub fn compile(schema: &serde_json::Value) -> AppResult<Self> {
13        rskit_schema::compile(schema).map(|compiled| Self { compiled })
14    }
15
16    /// Validate one structured record against this schema.
17    pub fn validate(&self, record: &serde_json::Value) -> AppResult<()> {
18        let result = self.compiled.validate(record);
19        if result.valid {
20            return Ok(());
21        }
22        let detail = result
23            .errors
24            .iter()
25            .map(ToString::to_string)
26            .collect::<Vec<_>>()
27            .join("; ");
28        Err(AppError::new(
29            ErrorCode::InvalidInput,
30            format!("dataset record failed schema validation: {detail}"),
31        ))
32    }
33}
34
35/// Validate one record against a JSON Schema.
36pub fn validate_record(schema: &DatasetSchema, record: &serde_json::Value) -> AppResult<()> {
37    schema.validate(record)
38}
39
40#[cfg(test)]
41mod tests {
42    use serde_json::json;
43
44    use super::*;
45
46    #[test]
47    fn dataset_schema_validates_records_and_reports_failures() {
48        let schema = DatasetSchema::compile(&json!({
49            "type": "object",
50            "required": ["id"],
51            "properties": {
52                "id": {"type": "string"},
53                "score": {"type": "number"}
54            }
55        }))
56        .unwrap();
57
58        validate_record(&schema, &json!({"id": "a", "score": 1.0})).unwrap();
59
60        let err = validate_record(&schema, &json!({"score": "bad"})).unwrap_err();
61        assert_eq!(err.code(), ErrorCode::InvalidInput);
62        assert!(
63            err.to_string()
64                .contains("dataset record failed schema validation")
65        );
66    }
67}