georust / geos

Rust bindings for GEOS
https://docs.rs/geos/
MIT License
122 stars 42 forks source link

try_into() not working: the trait bound `geos::Geometry<'_>: From<&geo_types::MultiPolygon<f64>>` is not satisfied #90

Open velvia opened 3 years ago

velvia commented 3 years ago

I must be doing something dumb.

Rust 2018 edition, Geos v8.0.1

Code:

use geo::{MultiPolygon};
use std::convert::TryInto;
use geos::{Geometry as GGeometry};

#[derive(Clone, Debug)]
pub struct GeomAndId {
    pub geom: MultiPolygon<f64>,
    pub id: u128,  // TODO: use core.Id etc.
}

impl GeomAndId {
    pub fn geos_geom(&self) -> Result<GGeometry<'static>, StringError> {
        let g: GGeometry = (&self.geom).try_into().map_err(|e| {
            format!("Geometry could not be converted to GEOS: {}", e).into()
        })?;
        Ok(g)
    }
}

Error:

error[E0277]: the trait bound `geos::Geometry<'_>: From<&geo_types::MultiPolygon<f64>>` is not satisfied
  --> geo.rs:20:41
   |
20 |         let g: GGeometry = (&self.geom).try_into().map_err(|e| {
   |                                         ^^^^^^^^ the trait `From<&geo_types::MultiPolygon<f64>>` is not implemented for `geos::Geometry<'_>`
   |
   = note: required because of the requirements on the impl of `Into<geos::Geometry<'_>>` for `&geo_types::MultiPolygon<f64>`
   = note: required because of the requirements on the impl of `TryFrom<&geo_types::MultiPolygon<f64>>` for `geos::Geometry<'_>`
   = note: required because of the requirements on the impl of `TryInto<geos::Geometry<'_>>` for `&geo_types::MultiPolygon<f64>`

It seems like somehow using try_into() is causing it to want the From trait, but clearly according to docs, the Geos TryFrom<&'a MultiPolygon<f64> trait exists, so what gives? Any help appreciated, thanks.

GuillaumeGomez commented 3 years ago

Try:

use geo::{MultiPolygon};
use std::convert::TryInto;
use geos::{Geometry as GGeometry};

#[derive(Clone, Debug)]
pub struct GeomAndId {
    pub geom: MultiPolygon<f64>,
    pub id: u128,  // TODO: use core.Id etc.
}

impl GeomAndId {
    pub fn geos_geom<'a>(&'a self) -> Result<GGeometry<'a>, StringError> {
        let g: GGeometry = self.geom.try_into().map_err(|e| {
            format!("Geometry could not be converted to GEOS: {}", e).into()
        })?;
        Ok(g)
    }
}

?

velvia commented 3 years ago

@GuillaumeGomez basically removing the (& ... ) reference wrapper right? Yeah, it results in the same error. :(

GuillaumeGomez commented 3 years ago

That's not the only thing which changed...

velvia commented 3 years ago

@GuillaumeGomez hmmm no dice... same error

error[E0277]: the trait bound `geos::Geometry<'_>: From<geo_types::MultiPolygon<f64>>` is not satisfied
  --> geo.rs:19:38
   |
19 |         let g: GGeometry = self.geom.try_into().map_err(|e| {
   |                                      ^^^^^^^^ the trait `From<geo_types::MultiPolygon<f64>>` is not implemented for `geos::Geometry<'_>`
   |
   = note: required because of the requirements on the impl of `Into<geos::Geometry<'_>>` for `geo_types::MultiPolygon<f64>`
   = note: required because of the requirements on the impl of `TryFrom<geo_types::MultiPolygon<f64>>` for `geos::Geometry<'_>`
   = note: required because of the requirements on the impl of `TryInto<geos::Geometry<'_>>` for `geo_types::MultiPolygon<f64>`
GuillaumeGomez commented 3 years ago

Ok, found the issue... We should add a doc(cfg(feature = "geo")) on the implementations... Anyway, modify your Cargo.toml file to enable the "geo" feature on geos. For example:

[dependencies]
geos = { version = "8.0", features = ["geo"] }

That fixes the issue. Wanna send a PR for the missing doc annotations?

velvia commented 3 years ago

Sure thing thanks

velvia commented 3 years ago

I'm currently stumped on a weird borrow checker error, I know it's not relevant to this issue but @GuillaumeGomez if you have seen this would appreciate any help. I posted it in Rust help cuz I'm not sure it's a geos issue. https://users.rust-lang.org/t/weird-borrow-checker-error-when-xxx-is-dropped-and-runs-the-drop-code-for-type-vec/62122

thanks

GuillaumeGomez commented 3 years ago

From what I saw, you're passing a temporary slice to a function while saying that the lifetime of the temporary slice is the same as the one of the GGeometry, so obviously, the compiler isn't so happy about that.