use serde_json::Value;
use super::custom_scalar::CustomScalar;
use crate::error::{FraiseQLError, Result};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum ValidationContext {
Serialize,
ParseValue,
ParseLiteral,
}
impl ValidationContext {
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Serialize => "serialize",
Self::ParseValue => "parseValue",
Self::ParseLiteral => "parseLiteral",
}
}
}
#[derive(Debug, Clone)]
pub struct ScalarValidationError {
pub scalar_name: String,
pub context: String,
pub message: String,
}
impl ScalarValidationError {
pub fn new(
scalar_name: impl Into<String>,
context: impl Into<String>,
message: impl Into<String>,
) -> Self {
Self {
scalar_name: scalar_name.into(),
context: context.into(),
message: message.into(),
}
}
#[must_use]
pub fn into_fraiseql_error(self) -> FraiseQLError {
FraiseQLError::validation(self.to_string())
}
}
impl std::fmt::Display for ScalarValidationError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Scalar \"{}\" validation failed in {}: {}",
self.scalar_name, self.context, self.message
)
}
}
impl std::error::Error for ScalarValidationError {}
pub fn validate_custom_scalar(
scalar: &dyn CustomScalar,
value: &Value,
context: ValidationContext,
) -> Result<Value> {
match context {
ValidationContext::Serialize => scalar.serialize(value).map_err(|e| {
FraiseQLError::validation(format!(
"Scalar \"{}\" validation failed in serialize: {}",
scalar.name(),
e
))
}),
ValidationContext::ParseValue => scalar.parse_value(value).map_err(|e| {
FraiseQLError::validation(format!(
"Scalar \"{}\" validation failed in parseValue: {}",
scalar.name(),
e
))
}),
ValidationContext::ParseLiteral => scalar.parse_literal(value).map_err(|e| {
FraiseQLError::validation(format!(
"Scalar \"{}\" validation failed in parseLiteral: {}",
scalar.name(),
e
))
}),
}
}
pub fn validate_custom_scalar_parse_value(
scalar: &dyn CustomScalar,
value: &Value,
) -> Result<Value> {
validate_custom_scalar(scalar, value, ValidationContext::ParseValue)
}