sqlitegis 0.1.0

SQLiteGIS: PostGIS-style spatial functions for SQLite in pure Rust.
Documentation
use thiserror::Error;

use crate::core::ewkb::geometry_type_name;

/// Errors returned by SQLiteGIS's core, SQLite, and Diesel layers.
#[derive(Debug, Error)]
pub enum SqliteGisError {
    /// The supplied bytes did not parse as a valid EWKB BLOB.
    #[error("invalid EWKB: {0}")]
    InvalidEwkb(String),

    /// A nested geozero codec error bubbled up from WKT, GeoJSON, or WKB I/O.
    #[error("geozero error: {0}")]
    Geozero(#[from] geozero::error::GeozeroError),

    /// The geometry's concrete type did not match what the operation needed.
    #[error("geometry is not a {expected}; got {actual}")]
    WrongType {
        /// Human readable name of the geometry type the caller expected.
        expected: &'static str,
        /// Human readable name of the geometry type that was supplied.
        actual: &'static str,
    },

    /// The operation cannot run on a geometry with the given coordinate
    /// dimensionality without silently dropping coordinates.
    #[error("unsupported coordinate dimensions: {dimensions} (operation would drop coordinates)")]
    UnsupportedDimensions {
        /// Label of the unsupported dimensional layout (e.g. `"XYZM"`).
        dimensions: &'static str,
    },

    /// A 1-based index argument was outside the addressable range.
    #[error("index out of bounds: {index} (len {len})")]
    OutOfBounds {
        /// The offending index as provided by the caller.
        index: i32,
        /// Length of the collection the index was checked against.
        len: usize,
    },

    /// The argument was syntactically valid but semantically rejected
    /// (e.g. a non-finite coordinate, an unknown SRID, an empty WKT string).
    #[error("{0}")]
    InvalidInput(String),

    /// An underlying `std::io::Error` from a reader or writer.
    #[error("io error: {0}")]
    Io(#[from] std::io::Error),
}

/// Result alias used by every fallible function in the crate.
pub type Result<T> = std::result::Result<T, SqliteGisError>;

impl SqliteGisError {
    /// Construct a `WrongType` error from an `expected` label and the actual
    /// geometry that was supplied. Centralises the `geometry_type_name`
    /// lookup so call sites don't have to repeat the boilerplate.
    pub fn wrong_type(expected: &'static str, got: &geo::Geometry<f64>) -> Self {
        Self::WrongType {
            expected,
            actual: geometry_type_name(got),
        }
    }
}