Skip to content

Commit

Permalink
Make other wkb and wkt variants generic (#188)
Browse files Browse the repository at this point in the history
This is a follow up to #171 to
make other WKB and WKT variants generic over any `AsRef<[u8]>` input

With this change, I think `WktString` and `WktStr` are redundant, but I
didn't want to make a breaking change. I _think_ this should be
non-breaking because `String` and `&str` can `AsRef` to `[u8]` right?
  • Loading branch information
kylebarron committed Jan 18, 2024
1 parent 24aeff5 commit 1d78b36
Show file tree
Hide file tree
Showing 13 changed files with 124 additions and 75 deletions.
12 changes: 6 additions & 6 deletions geozero/src/geo_types/geo_types_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,8 @@ mod test {

#[test]
fn geometry_collection() {
use crate::wkt::WktStr;
let wkt = WktStr("GEOMETRYCOLLECTION(POINT(1 2),LINESTRING(1 2,3 4))");
use crate::wkt::Wkt;
let wkt = Wkt("GEOMETRYCOLLECTION(POINT(1 2),LINESTRING(1 2,3 4))");
let actual = wkt.to_geo().unwrap();

use geo_types::{line_string, point, Geometry, GeometryCollection};
Expand All @@ -257,8 +257,8 @@ mod test {

#[test]
fn nested_geometry_collections() {
use crate::wkt::WktStr;
let wkt = WktStr("GEOMETRYCOLLECTION(POINT(1 2),GEOMETRYCOLLECTION(LINESTRING(1 2,3 4), MULTIPOINT(1 2, 3 4, 5 6)),POINT(7 8))");
use crate::wkt::Wkt;
let wkt = Wkt("GEOMETRYCOLLECTION(POINT(1 2),GEOMETRYCOLLECTION(LINESTRING(1 2,3 4), MULTIPOINT(1 2, 3 4, 5 6)),POINT(7 8))");
let actual = wkt.to_geo().unwrap();

use geo_types::{line_string, point, Geometry, GeometryCollection, MultiPoint};
Expand All @@ -282,8 +282,8 @@ mod test {

#[test]
fn complex() {
use crate::wkt::WktStr;
let wkt = WktStr("GEOMETRYCOLLECTION (LINESTRING (6308869.40378 356821.22669, 6308867.893 356822.41744, 6308852.75314 356830.22159, 6308869.92754 356844.26638), LINESTRING (6308755.07971 356674.51686, 6308784.81355 356719.16757, 6308815.20022 356765.46178, 6308829.63774 356763.22832, 6308852.87023 356759.82402, 6308867.19982 356771.06823, 6308875.40631 356796.20162, 6308872.51907 356815.17242), LINESTRING (6308874.12086 356813.73392, 6308876.83028 356795.77697, 6308868.23871 356770.06254, 6308853.09618 356758.29456, 6308815.86529 356763.89689, 6308799.76731 356739.37835, 6308747.77971 356662.11613, 6308746.55411 356661.61702, 6308744.06545 356657.72563, 6308731.77184 356668.45076, 6308699.45221 356683.15463, 6308682.44689 356684.63193, 6308654.96629 356683.66846, 6308636.13879 356680.0482, 6308618.19888 356671.76352, 6308608.41685 356661.79428, 6308578.7973 356592.35062, 6308545.33908 356542.14886, 6308517.52088 356509.38474, 6308505.40266 356506.84141, 6308493.59689 356506.98067, 6308375.07918 356520.46209), LINESTRING (6308877.92941 356819.50984, 6309072.26249 356514.14689, 6309073.44938 356513.3739, 6309076.25423 356511.31751, 6309096.05004 356528.52014, 6309103.33938 356535.32615, 6309107.49584 356539.20699, 6309107.78601 356539.47793, 6309119.09139 356550.03322, 6309137.04465 356567.13752, 6309137.6323 356567.69515, 6309138.92096 356568.91355, 6309138.46355 356569.69798, 6309150.68532 356566.34027, 6309151.94333 356567.03108, 6309157.81557 356565.41779, 6309161.54152 356564.33408, 6309174.6464 356579.77423, 6309175.71622 356581.0361, 6309177.25892 356582.84545, 6309225.37695 356611.76515, 6309226.90588 356612.65173, 6309229.72021 356614.34101, 6309232.64678 356598.75445, 6309244.10246 356528.49893, 6309251.20809 356487.90256, 6309252.35489 356481.34967, 6309258.41778 356442.34047, 6309258.56036 356441.19511, 6309258.76115 356440.13123, 6309260.99127 356426.22389, 6309258.49745 356425.57244, 6309240.94882 356422.48836, 6309240.53276 356422.37171, 6309240.10958 356422.29068), LINESTRING (6308870.96141 356823.05522, 6308881.43519 356846.04558, 6308859.94336 356857.75024, 6308859.6305 356857.95378, 6308893.96675 356932.14467, 6308921.19517 356993.60222, 6308942.68768 357040.82051, 6308961.42173 357079.52481, 6308976.48471 357108.08898, 6308992.14194 357136.52543, 6309018.60922 357184.68892, 6309024.87557 357193.57884, 6309025.31785 357194.20629, 6309028.73486 357199.05392, 6309045.86114 357220.97586, 6309078.85225 357261.01696, 6309131.17986 357323.22098, 6309184.03434 357388.33409, 6309212.61182 357423.54026, 6309252.80543 357467.20429, 6309288.51836 357504.59499, 6309318.98068 357536.37443, 6309366.01084 357588.07961, 6309383.32941 357609.89089, 6309383.33718 357609.92579, 6309383.36584 357611.49516), POLYGON ((6309096.87876754 357058.96992573235, 6309100.9240038069 357067.89795246266, 6309103.1497403858 357077.44361610821, 6309103.4704434676 357087.24008216924, 6309101.8737886148 357096.91087794991, 6309098.421134375 357106.08436019259, 6309093.2451643161 357114.40799712023, 6309086.5447880644 357121.56191603432, 6309078.5774973193 357127.27119584358, 6309013.594489282 357164.78915304772, 6309004.6664625369 357168.8343893392, 6308995.1207988719 357171.06012593472, 6308985.3243327877 357171.38082902494, 6308975.6535369828 357169.78417417, 6308966.4800547194 357166.33151992067, 6308958.156417775 357161.1555498438, 6308951.0024988521 357154.45517356717, 6308945.293219042 357146.48788279406, 6308795.0043396624 356886.1799069175, 6308790.959103398 356877.251880196, 6308788.7333668182 356867.70621655986, 6308788.4126637317 356857.90975050797, 6308790.0093185771 356848.2389547351, 6308793.4619728047 356839.0654724979, 6308798.6379428506 356830.74183557258, 6308805.3383190883 356823.587916657, 6308813.3056098176 356817.87863684172, 6308878.2886178084 356780.36067953659, 6308887.2166445563 356776.315443229, 6308896.7623082288 356774.08970661991, 6308906.5587743223 356773.76900351944, 6308916.2295701364 356775.36565836804, 6308925.403052411 356778.81831261492, 6308933.7266893657 356783.99428269314, 6308940.8806082979 356790.69465897442, 6308946.5898881136 356798.66194975481, 6309096.87876754 357058.96992573235)))");
use crate::wkt::Wkt;
let wkt = Wkt("GEOMETRYCOLLECTION (LINESTRING (6308869.40378 356821.22669, 6308867.893 356822.41744, 6308852.75314 356830.22159, 6308869.92754 356844.26638), LINESTRING (6308755.07971 356674.51686, 6308784.81355 356719.16757, 6308815.20022 356765.46178, 6308829.63774 356763.22832, 6308852.87023 356759.82402, 6308867.19982 356771.06823, 6308875.40631 356796.20162, 6308872.51907 356815.17242), LINESTRING (6308874.12086 356813.73392, 6308876.83028 356795.77697, 6308868.23871 356770.06254, 6308853.09618 356758.29456, 6308815.86529 356763.89689, 6308799.76731 356739.37835, 6308747.77971 356662.11613, 6308746.55411 356661.61702, 6308744.06545 356657.72563, 6308731.77184 356668.45076, 6308699.45221 356683.15463, 6308682.44689 356684.63193, 6308654.96629 356683.66846, 6308636.13879 356680.0482, 6308618.19888 356671.76352, 6308608.41685 356661.79428, 6308578.7973 356592.35062, 6308545.33908 356542.14886, 6308517.52088 356509.38474, 6308505.40266 356506.84141, 6308493.59689 356506.98067, 6308375.07918 356520.46209), LINESTRING (6308877.92941 356819.50984, 6309072.26249 356514.14689, 6309073.44938 356513.3739, 6309076.25423 356511.31751, 6309096.05004 356528.52014, 6309103.33938 356535.32615, 6309107.49584 356539.20699, 6309107.78601 356539.47793, 6309119.09139 356550.03322, 6309137.04465 356567.13752, 6309137.6323 356567.69515, 6309138.92096 356568.91355, 6309138.46355 356569.69798, 6309150.68532 356566.34027, 6309151.94333 356567.03108, 6309157.81557 356565.41779, 6309161.54152 356564.33408, 6309174.6464 356579.77423, 6309175.71622 356581.0361, 6309177.25892 356582.84545, 6309225.37695 356611.76515, 6309226.90588 356612.65173, 6309229.72021 356614.34101, 6309232.64678 356598.75445, 6309244.10246 356528.49893, 6309251.20809 356487.90256, 6309252.35489 356481.34967, 6309258.41778 356442.34047, 6309258.56036 356441.19511, 6309258.76115 356440.13123, 6309260.99127 356426.22389, 6309258.49745 356425.57244, 6309240.94882 356422.48836, 6309240.53276 356422.37171, 6309240.10958 356422.29068), LINESTRING (6308870.96141 356823.05522, 6308881.43519 356846.04558, 6308859.94336 356857.75024, 6308859.6305 356857.95378, 6308893.96675 356932.14467, 6308921.19517 356993.60222, 6308942.68768 357040.82051, 6308961.42173 357079.52481, 6308976.48471 357108.08898, 6308992.14194 357136.52543, 6309018.60922 357184.68892, 6309024.87557 357193.57884, 6309025.31785 357194.20629, 6309028.73486 357199.05392, 6309045.86114 357220.97586, 6309078.85225 357261.01696, 6309131.17986 357323.22098, 6309184.03434 357388.33409, 6309212.61182 357423.54026, 6309252.80543 357467.20429, 6309288.51836 357504.59499, 6309318.98068 357536.37443, 6309366.01084 357588.07961, 6309383.32941 357609.89089, 6309383.33718 357609.92579, 6309383.36584 357611.49516), POLYGON ((6309096.87876754 357058.96992573235, 6309100.9240038069 357067.89795246266, 6309103.1497403858 357077.44361610821, 6309103.4704434676 357087.24008216924, 6309101.8737886148 357096.91087794991, 6309098.421134375 357106.08436019259, 6309093.2451643161 357114.40799712023, 6309086.5447880644 357121.56191603432, 6309078.5774973193 357127.27119584358, 6309013.594489282 357164.78915304772, 6309004.6664625369 357168.8343893392, 6308995.1207988719 357171.06012593472, 6308985.3243327877 357171.38082902494, 6308975.6535369828 357169.78417417, 6308966.4800547194 357166.33151992067, 6308958.156417775 357161.1555498438, 6308951.0024988521 357154.45517356717, 6308945.293219042 357146.48788279406, 6308795.0043396624 356886.1799069175, 6308790.959103398 356877.251880196, 6308788.7333668182 356867.70621655986, 6308788.4126637317 356857.90975050797, 6308790.0093185771 356848.2389547351, 6308793.4619728047 356839.0654724979, 6308798.6379428506 356830.74183557258, 6308805.3383190883 356823.587916657, 6308813.3056098176 356817.87863684172, 6308878.2886178084 356780.36067953659, 6308887.2166445563 356776.315443229, 6308896.7623082288 356774.08970661991, 6308906.5587743223 356773.76900351944, 6308916.2295701364 356775.36565836804, 6308925.403052411 356778.81831261492, 6308933.7266893657 356783.99428269314, 6308940.8806082979 356790.69465897442, 6308946.5898881136 356798.66194975481, 6309096.87876754 357058.96992573235)))");

assert!(wkt.to_geo().is_ok());
}
Expand Down
4 changes: 2 additions & 2 deletions geozero/src/geojson/geojson_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ impl<W: Write> PropertyProcessor for GeoJsonWriter<W> {
mod test {
use super::*;
use crate::geojson::read_geojson;
use crate::wkt::WktStr;
use crate::wkt::Wkt;
use crate::ToJson;

#[test]
Expand Down Expand Up @@ -431,7 +431,7 @@ mod test {
r#"{"type": "Point", "coordinates": [10,20]}"#
);

let geom = WktStr("POINT EMPTY");
let geom = Wkt("POINT EMPTY");
assert_eq!(
&geom.to_json().unwrap(),
r#"{"type": "Point", "coordinates": []}"#
Expand Down
4 changes: 2 additions & 2 deletions geozero/src/gpkg/geopackage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ impl<'de, T: FromWkb + Sized> Decode<'de, Sqlite> for wkb::Decode<T> {
}
}

impl sqlx::Type<Sqlite> for wkb::GpkgWkb {
impl<B: AsRef<[u8]>> sqlx::Type<Sqlite> for wkb::GpkgWkb<B> {
fn type_info() -> SqliteTypeInfo {
<Vec<u8> as sqlx::Type<Sqlite>>::type_info()
}
}

impl<'de> Decode<'de, Sqlite> for wkb::GpkgWkb {
impl<'de> Decode<'de, Sqlite> for wkb::GpkgWkb<Vec<u8>> {
fn decode(value: SqliteValueRef<'de>) -> Result<Self, BoxDynError> {
if value.is_null() {
return Ok(wkb::GpkgWkb(Vec::new()));
Expand Down
2 changes: 1 addition & 1 deletion geozero/src/postgis/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ pub mod sqlx {}
/// #[diesel(table_name = geometries)]
/// pub struct Geom {
/// pub name: String,
/// pub geom: Option<Ewkb>,
/// pub geom: Option<Ewkb<Vec<u8>>>,
/// }
///
/// pub fn establish_connection() -> PgConnection {
Expand Down
12 changes: 6 additions & 6 deletions geozero/src/postgis/postgis_diesel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,27 @@ pub mod sql_types {
pub struct Geography;
}

impl ToSql<Geometry, Pg> for Ewkb {
impl<B: AsRef<[u8]> + std::fmt::Debug> ToSql<Geometry, Pg> for Ewkb<B> {
fn to_sql(&self, out: &mut Output<Pg>) -> serialize::Result {
out.write_all(&self.0)?;
out.write_all(self.0.as_ref())?;
Ok(IsNull::No)
}
}

impl ToSql<Geography, Pg> for Ewkb {
impl<B: AsRef<[u8]> + std::fmt::Debug> ToSql<Geography, Pg> for Ewkb<B> {
fn to_sql(&self, out: &mut Output<Pg>) -> serialize::Result {
out.write_all(&self.0)?;
out.write_all(self.0.as_ref())?;
Ok(IsNull::No)
}
}

impl FromSql<Geometry, Pg> for Ewkb {
impl FromSql<Geometry, Pg> for Ewkb<Vec<u8>> {
fn from_sql(bytes: pg::PgValue) -> deserialize::Result<Self> {
Ok(Self(bytes.as_bytes().to_vec()))
}
}

impl FromSql<Geography, Pg> for Ewkb {
impl FromSql<Geography, Pg> for Ewkb<Vec<u8>> {
fn from_sql(bytes: pg::PgValue) -> deserialize::Result<Self> {
Ok(Self(bytes.as_bytes().to_vec()))
}
Expand Down
2 changes: 1 addition & 1 deletion geozero/src/postgis/postgis_postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl<T: FromWkb + Sized> FromSql<'_> for wkb::Decode<T> {
}
}

impl FromSql<'_> for wkb::Ewkb {
impl FromSql<'_> for wkb::Ewkb<Vec<u8>> {
fn from_sql(_ty: &Type, raw: &[u8]) -> Result<Self, Box<dyn std::error::Error + Sync + Send>> {
Ok(wkb::Ewkb(raw.to_vec()))
}
Expand Down
6 changes: 3 additions & 3 deletions geozero/src/postgis/postgis_sqlx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,19 @@ impl<'de, T: FromWkb + Sized> Decode<'de, Postgres> for wkb::Decode<T> {
}
}

impl sqlx::Type<Postgres> for wkb::Ewkb {
impl<B: AsRef<[u8]>> sqlx::Type<Postgres> for wkb::Ewkb<B> {
fn type_info() -> PgTypeInfo {
PgTypeInfo::with_name("geometry")
}
}

impl PgHasArrayType for wkb::Ewkb {
impl<B: AsRef<[u8]>> PgHasArrayType for wkb::Ewkb<B> {
fn array_type_info() -> PgTypeInfo {
PgTypeInfo::with_name("_geometry")
}
}

impl<'de> Decode<'de, Postgres> for wkb::Ewkb {
impl<'de> Decode<'de, Postgres> for wkb::Ewkb<Vec<u8>> {
fn decode(value: PgValueRef<'de>) -> Result<Self, BoxDynError> {
if value.is_null() {
return Ok(wkb::Ewkb(Vec::new()));
Expand Down
26 changes: 13 additions & 13 deletions geozero/src/wkb/wkb_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,38 +26,38 @@ impl<B: AsRef<[u8]>> GeozeroGeometry for Wkb<B> {
)]
#[cfg_attr(feature = "with-postgis-diesel", diesel(sql_type = Geometry))]
#[cfg_attr(feature = "with-postgis-diesel", diesel(sql_type = Geography))]
pub struct Ewkb(pub Vec<u8>);
pub struct Ewkb<B: AsRef<[u8]>>(pub B);

impl GeozeroGeometry for Ewkb {
impl<B: AsRef<[u8]>> GeozeroGeometry for Ewkb<B> {
fn process_geom<P: GeomProcessor>(&self, processor: &mut P) -> Result<()> {
process_ewkb_geom(&mut self.0.as_slice(), processor)
process_ewkb_geom(&mut self.0.as_ref(), processor)
}
}

/// GeoPackage WKB reader.
pub struct GpkgWkb(pub Vec<u8>);
pub struct GpkgWkb<B: AsRef<[u8]>>(pub B);

impl GeozeroGeometry for GpkgWkb {
impl<B: AsRef<[u8]>> GeozeroGeometry for GpkgWkb<B> {
fn process_geom<P: GeomProcessor>(&self, processor: &mut P) -> Result<()> {
process_gpkg_geom(&mut self.0.as_slice(), processor)
process_gpkg_geom(&mut self.0.as_ref(), processor)
}
}

/// GeoPackage WKB reader.
pub struct SpatiaLiteWkb(pub Vec<u8>);
pub struct SpatiaLiteWkb<B: AsRef<[u8]>>(pub B);

impl GeozeroGeometry for SpatiaLiteWkb {
impl<B: AsRef<[u8]>> GeozeroGeometry for SpatiaLiteWkb<B> {
fn process_geom<P: GeomProcessor>(&self, processor: &mut P) -> Result<()> {
process_spatialite_geom(&mut self.0.as_slice(), processor)
process_spatialite_geom(&mut self.0.as_ref(), processor)
}
}

/// GeoPackage WKB reader.
pub struct MySQLWkb(pub Vec<u8>);
/// MySQL WKB reader.
pub struct MySQLWkb<B: AsRef<[u8]>>(pub B);

impl GeozeroGeometry for MySQLWkb {
impl<B: AsRef<[u8]>> GeozeroGeometry for MySQLWkb<B> {
fn process_geom<P: GeomProcessor>(&self, processor: &mut P) -> Result<()> {
process_mysql_geom(&mut self.0.as_slice(), processor)
process_mysql_geom(&mut self.0.as_ref(), processor)
}
}

Expand Down
32 changes: 31 additions & 1 deletion geozero/src/wkt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,37 @@ pub(crate) mod conversion {
mod wkb {
use crate::error::Result;
use crate::wkb::{FromWkb, WkbDialect};
use crate::wkt::{EwktString, WktDialect, WktString, WktWriter};
#[allow(deprecated)]
use crate::wkt::{Ewkt, EwktString, Wkt, WktDialect, WktString, WktWriter};
use crate::CoordDimensions;
use std::io::Read;

impl FromWkb for Wkt<String> {
fn from_wkb<R: Read>(rdr: &mut R, dialect: WkbDialect) -> Result<Self> {
let mut out: Vec<u8> = Vec::new();
let mut writer = WktWriter::new(&mut out);
crate::wkb::process_wkb_type_geom(rdr, &mut writer, dialect)?;
let wkt = String::from_utf8(out).map_err(|_| {
crate::error::GeozeroError::Geometry("Invalid UTF-8 encoding".to_string())
})?;
Ok(Wkt(wkt))
}
}

impl FromWkb for Ewkt<String> {
fn from_wkb<R: Read>(rdr: &mut R, dialect: WkbDialect) -> Result<Self> {
let mut out: Vec<u8> = Vec::new();
let mut writer =
WktWriter::with_opts(&mut out, WktDialect::Ewkt, CoordDimensions::xyzm(), None);
crate::wkb::process_wkb_type_geom(rdr, &mut writer, dialect)?;
let wkt = String::from_utf8(out).map_err(|_| {
crate::error::GeozeroError::Geometry("Invalid UTF-8 encoding".to_string())
})?;
Ok(Ewkt(wkt))
}
}

#[allow(deprecated)]
impl FromWkb for WktString {
fn from_wkb<R: Read>(rdr: &mut R, dialect: WkbDialect) -> Result<Self> {
let mut out: Vec<u8> = Vec::new();
Expand All @@ -74,10 +101,12 @@ mod wkb {
let wkt = String::from_utf8(out).map_err(|_| {
crate::error::GeozeroError::Geometry("Invalid UTF-8 encoding".to_string())
})?;
#[allow(deprecated)]
Ok(WktString(wkt))
}
}

#[allow(deprecated)]
impl FromWkb for EwktString {
fn from_wkb<R: Read>(rdr: &mut R, dialect: WkbDialect) -> Result<Self> {
let mut out: Vec<u8> = Vec::new();
Expand All @@ -87,6 +116,7 @@ mod wkb {
let wkt = String::from_utf8(out).map_err(|_| {
crate::error::GeozeroError::Geometry("Invalid UTF-8 encoding".to_string())
})?;
#[allow(deprecated)]
Ok(EwktString(wkt))
}
}
Expand Down
Loading

0 comments on commit 1d78b36

Please sign in to comment.