postgrest-parser 0.2.0

PostgREST URL-to-SQL parser for Rust and WASM
Documentation
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Field {
    pub name: String,
    pub json_path: Vec<JsonOp>,
    pub cast: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum JsonOp {
    Arrow(String),
    DoubleArrow(String),
    ArrayIndex(i32),
}

impl Field {
    pub fn new(name: impl Into<String>) -> Self {
        Self {
            name: name.into(),
            json_path: Vec::new(),
            cast: None,
        }
    }

    pub fn with_json_path(mut self, ops: Vec<JsonOp>) -> Self {
        self.json_path = ops;
        self
    }

    pub fn with_cast(mut self, cast: impl Into<String>) -> Self {
        self.cast = Some(cast.into());
        self
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_field_new() {
        let field = Field::new("id");
        assert_eq!(field.name, "id");
        assert!(field.json_path.is_empty());
        assert!(field.cast.is_none());
    }

    #[test]
    fn test_field_with_json_path() {
        let field = Field::new("data").with_json_path(vec![JsonOp::Arrow("key".to_string())]);
        assert_eq!(field.name, "data");
        assert_eq!(field.json_path.len(), 1);
    }

    #[test]
    fn test_field_with_cast() {
        let field = Field::new("price").with_cast("numeric");
        assert_eq!(field.name, "price");
        assert_eq!(field.cast, Some("numeric".to_string()));
    }

    #[test]
    fn test_json_op_serialization() {
        let op = JsonOp::Arrow("key".to_string());
        let json = serde_json::to_string(&op).unwrap();
        assert!(json.contains("arrow"));
    }
}