Skip to main content

vld/schema/
input.rs

1use serde_json::Value;
2use std::borrow::Cow;
3
4use crate::error::{IssueCode, VldError};
5
6/// Trait for types that can be used as input to schema parsing.
7///
8/// Implemented for JSON strings (`str`, `String`), raw bytes (`[u8]`), file
9/// paths (`Path`, `PathBuf`) and `serde_json::Value` (borrowed, never cloned).
10pub trait VldInput {
11    /// The input as a JSON value: borrowed when it already is one, parsed otherwise.
12    fn to_json_value(&self) -> Result<Cow<'_, Value>, VldError>;
13}
14
15impl VldInput for Value {
16    fn to_json_value(&self) -> Result<Cow<'_, Value>, VldError> {
17        Ok(Cow::Borrowed(self))
18    }
19}
20
21fn invalid_json(e: serde_json::Error) -> VldError {
22    VldError::single(IssueCode::ParseError, format!("Invalid JSON: {}", e))
23}
24
25impl VldInput for str {
26    fn to_json_value(&self) -> Result<Cow<'_, Value>, VldError> {
27        serde_json::from_str(self)
28            .map(Cow::Owned)
29            .map_err(invalid_json)
30    }
31}
32
33impl VldInput for String {
34    fn to_json_value(&self) -> Result<Cow<'_, Value>, VldError> {
35        self.as_str().to_json_value()
36    }
37}
38
39impl VldInput for [u8] {
40    fn to_json_value(&self) -> Result<Cow<'_, Value>, VldError> {
41        serde_json::from_slice(self)
42            .map(Cow::Owned)
43            .map_err(invalid_json)
44    }
45}
46
47impl VldInput for std::path::Path {
48    fn to_json_value(&self) -> Result<Cow<'_, Value>, VldError> {
49        let content = std::fs::read_to_string(self).map_err(|e| {
50            VldError::single(IssueCode::IoError, format!("Failed to read file: {}", e))
51        })?;
52        serde_json::from_str(&content)
53            .map(Cow::Owned)
54            .map_err(invalid_json)
55    }
56}
57
58impl VldInput for std::path::PathBuf {
59    fn to_json_value(&self) -> Result<Cow<'_, Value>, VldError> {
60        self.as_path().to_json_value()
61    }
62}