//! Custom error types for dynojson operations.
//!
//! Uses [`thiserror`] for ergonomic, well-behaved error types that implement
//! `std::error::Error` and `Display`.

use thiserror::Error;

/// Errors that can occur during marshall/unmarshall or property extraction.
#[derive(Debug, Error)]
pub enum DynoError {
    /// The input string is not valid JSON.
    #[error("Invalid JSON: {0}")]
    InvalidJson(#[from] serde_json::Error),

    /// An unrecognised DynamoDB type descriptor was encountered during unmarshall.
    #[error("Unknown DynamoDB type descriptor: {key}")]
    UnknownType { key: String },

    /// A DynamoDB `N` value could not be interpreted as a finite JSON number.
    #[error("Invalid number value in DynamoDB JSON: {value}")]
    InvalidNumber { value: String },

    /// The property path is empty.
    #[error("Property path is empty")]
    EmptyPath,

    /// The property path contains more than one wildcard (`*`).
    #[error("Property should have no more than one asterisk (*)")]
    TooManyWildcards,

    /// A wildcard (`*`) was used on a value that is not a JSON array.
    #[error("Cannot get array items of a non-array")]
    WildcardOnNonArray,

    /// Attempted to extract a property from a non-object/non-array value.
    #[error("Cannot get property of a non-object")]
    PropertyOfNonObject,

    /// The requested property was not found in the input JSON.
    #[error("Property not found: '{path}'")]
    PropertyNotFound { path: String },

    /// The property resolved to a scalar, not an object or array, so it cannot
    /// be marshalled/unmarshalled.
    #[error("Property is not an object: '{path}'")]
    PropertyNotObject { path: String },
}

/// Convenience alias used throughout the crate.
pub type Result<T> = std::result::Result<T, DynoError>;
