lwgeom 0.0.2

Rust bindings for the LWGEOM geometry library.
Documentation
use std::ffi::{CStr, CString};
use std::marker::PhantomData;
use std::os::raw::c_char;
use std::ptr::NonNull;

use lwgeom_sys::*;

use crate::{LWGeomError, Result};

pub struct LWGeom<'a>(NonNull<LWGEOM>, PhantomData<&'a ()>);

impl<'a> LWGeom<'a> {
    pub fn new_from_wkt(wkt: &str) -> Result<Self> {
        let c_wkt = CString::new(wkt)?;
        let p_geom = unsafe { lwgeom_from_wkt(c_wkt.as_ptr(), LW_PARSER_CHECK_NONE as c_char) };
        Ok(Self(
            NonNull::new(p_geom).ok_or(LWGeomError::NullPtrError)?,
            PhantomData,
        ))
    }

    pub fn to_ewkt(&self) -> Result<String> {
        let c_ewkt = unsafe { CStr::from_ptr(lwgeom_to_ewkt(self.0.as_ptr())) };
        Ok(c_ewkt.to_string_lossy().to_string())
    }

    pub fn split(&self, blade: &LWGeom) -> Result<Self> {
        let p_geom = unsafe { lwgeom_split(self.0.as_ptr(), blade.0.as_ptr()) };
        Ok(Self(
            NonNull::new(p_geom).ok_or(LWGeomError::NullPtrError)?,
            PhantomData,
        ))
    }
}

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

    #[test]
    fn it_works() {
        let result = LWGeom::new_from_wkt("MULTILINESTRING((10 10,190 190), (15 15,30 30,100 90))")
            .unwrap()
            .split(&LWGeom::new_from_wkt("POINT(30 30)").unwrap())
            .unwrap()
            .to_ewkt()
            .unwrap();
        assert_eq!(
            result,
            "GEOMETRYCOLLECTION(LINESTRING(10 10,30 30),LINESTRING(30 30,190 190),LINESTRING(15 15,30 30),LINESTRING(30 30,100 90))"
        );
    }
}