opencellid 0.2.0

Rust client library for the OpenCellID API — sync and async clients with tracing, structured errors, and bounded I/O.
Documentation
//! Strongly-typed query parameters for endpoints.

use crate::types::{Bbox, Lac, Mcc, Mnc, Radio};

/// Parameters for `cell/getInArea` and `cell/getInAreaSize`.
///
/// `bbox` is required; everything else narrows the query.
#[derive(Debug, Clone)]
pub struct AreaQuery {
    /// Bounding box to search within.
    pub bbox: Bbox,
    /// Restrict to a specific country.
    pub mcc: Option<Mcc>,
    /// Restrict to a specific network operator.
    pub mnc: Option<Mnc>,
    /// Restrict to a specific location area.
    pub lac: Option<Lac>,
    /// Restrict to a specific radio technology.
    pub radio: Option<Radio>,
}

impl AreaQuery {
    /// Start a query for cells inside `bbox` with no other filters.
    pub fn new(bbox: Bbox) -> Self {
        Self { bbox, mcc: None, mnc: None, lac: None, radio: None }
    }

    /// Restrict to a specific MCC.
    pub fn mcc(mut self, mcc: Mcc) -> Self {
        self.mcc = Some(mcc);
        self
    }

    /// Restrict to a specific MNC.
    pub fn mnc(mut self, mnc: Mnc) -> Self {
        self.mnc = Some(mnc);
        self
    }

    /// Restrict to a specific LAC.
    pub fn lac(mut self, lac: Lac) -> Self {
        self.lac = Some(lac);
        self
    }

    /// Restrict to a specific radio technology.
    pub fn radio(mut self, radio: Radio) -> Self {
        self.radio = Some(radio);
        self
    }
}

/// Parameters for `cell/getInArea` — adds pagination on top of [`AreaQuery`].
///
/// Default response format on the wire is CSV (parsed into [`crate::Cell`] values).
#[derive(Debug, Clone)]
pub struct GetCellsInAreaParams {
    /// Geographic and operator filters.
    pub query: AreaQuery,
    /// Maximum cells to return per call. Server caps at 50.
    pub limit: Option<u32>,
    /// Pagination offset.
    pub offset: Option<u32>,
}

impl GetCellsInAreaParams {
    /// Start parameters for the given query.
    pub fn new(query: AreaQuery) -> Self {
        Self { query, limit: None, offset: None }
    }

    /// Set page size (server caps at 50).
    pub fn limit(mut self, limit: u32) -> Self {
        self.limit = Some(limit);
        self
    }

    /// Set pagination offset.
    pub fn offset(mut self, offset: u32) -> Self {
        self.offset = Some(offset);
        self
    }
}

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

    fn bbox() -> Bbox {
        Bbox::new(0.0, 0.0, 1.0, 1.0).unwrap()
    }

    #[test]
    fn area_query_setters_cover_all_fields() {
        let q = AreaQuery::new(bbox()).mcc(250).mnc(1).lac(7800).radio(crate::types::Radio::Lte);
        assert_eq!(q.mcc, Some(250));
        assert_eq!(q.mnc, Some(1));
        assert_eq!(q.lac, Some(7800));
        assert_eq!(q.radio, Some(crate::types::Radio::Lte));
    }

    #[test]
    fn area_query_last_setter_wins() {
        let q = AreaQuery::new(bbox()).mcc(1).mcc(2);
        assert_eq!(q.mcc, Some(2));
    }

    #[test]
    fn get_cells_in_area_params_pagination() {
        let p = GetCellsInAreaParams::new(AreaQuery::new(bbox()))
            .limit(50)
            .offset(100);
        assert_eq!(p.limit, Some(50));
        assert_eq!(p.offset, Some(100));
    }
}