use super::SchemaType;
use crate::ast::{EntityUID, Expr, ExprKind, Name, RestrictedExpr, RestrictedExpressionError};
use crate::extensions::ExtensionsError;
use smol_str::SmolStr;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum JsonDeserializationError {
#[error("{0}")]
Serde(#[from] serde_json::Error),
#[error(transparent)]
ExprParseError(crate::parser::err::ParseError),
#[error(transparent)]
EntityParseError(crate::parser::err::ParseError),
#[error(transparent)]
ExtnParseError(crate::parser::err::ParseError),
#[error(transparent)]
RestrictedExpressionError(#[from] RestrictedExpressionError),
#[error(transparent)]
ExtensionsError(#[from] ExtensionsError),
#[error("{ctx}, expected a literal entity reference, but got {got}")]
ExpectedLiteralEntityRef {
ctx: JsonDeserializationErrorContext,
got: Box<Expr>,
},
#[error("{ctx}, expected an extension value, but got {got}")]
ExpectedExtnValue {
ctx: JsonDeserializationErrorContext,
got: Box<Expr>,
},
#[error("Expected Context to be a record, but got {got}")]
ExpectedContextToBeRecord {
got: Box<RestrictedExpr>,
},
#[error("Extension constructor for {arg_type} -> {return_type} not found")]
ImpliedConstructorNotFound {
return_type: Box<SchemaType>,
arg_type: Box<SchemaType>,
},
#[error("Attribute {:?} on {uid} shouldn't exist according to the schema", &.attr)]
UnexpectedEntityAttr {
uid: EntityUID,
attr: SmolStr,
},
#[error("{ctx}, record attribute {record_attr:?} shouldn't exist according to the schema")]
UnexpectedRecordAttr {
ctx: JsonDeserializationErrorContext,
record_attr: SmolStr,
},
#[error("Expected {uid} to have an attribute {attr:?}, but it didn't")]
MissingRequiredEntityAttr {
uid: EntityUID,
attr: SmolStr,
},
#[error("{ctx}, expected the record to have an attribute {record_attr:?}, but it didn't")]
MissingRequiredRecordAttr {
ctx: JsonDeserializationErrorContext,
record_attr: SmolStr,
},
#[error("{ctx}, type mismatch: attribute was expected to have type {expected}, but actually has type {actual}")]
TypeMismatch {
ctx: JsonDeserializationErrorContext,
expected: Box<SchemaType>,
actual: Box<SchemaType>,
},
#[error("{ctx}, set elements have different types: {ty1} and {ty2}")]
HeterogeneousSet {
ctx: JsonDeserializationErrorContext,
ty1: Box<SchemaType>,
ty2: Box<SchemaType>,
},
}
#[derive(Debug, Error)]
pub enum JsonSerializationError {
#[error("{0}")]
Serde(#[from] serde_json::Error),
#[error("extension-function calls with 0 arguments are not currently supported in our JSON format. found call of {func}")]
ExtnCall0Arguments {
func: Name,
},
#[error("extension-function calls with 2 or more arguments are not currently supported in our JSON format. found call of {func}")]
ExtnCall2OrMoreArguments {
func: Name,
},
#[error("record uses reserved key: {key}")]
ReservedKey {
key: SmolStr,
},
#[error("unexpected restricted expression: {kind:?}")]
UnexpectedRestrictedExprKind {
kind: ExprKind,
},
}
#[derive(Debug, Clone)]
pub enum JsonDeserializationErrorContext {
EntityAttribute {
uid: EntityUID,
attr: SmolStr,
},
EntityParents {
uid: EntityUID,
},
EntityUid,
Context,
}
impl std::fmt::Display for JsonDeserializationErrorContext {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::EntityAttribute { uid, attr } => write!(f, "In attribute {attr:?} on {uid}"),
Self::EntityParents { uid } => write!(f, "In parents field of {uid}"),
Self::EntityUid => write!(f, "In uid field of <unknown entity>"),
Self::Context => write!(f, "While parsing Context"),
}
}
}