Hi, am noticing as I learn Rust, it seems the signatures of 3rd party functions used in the implementation of my own functions have a great effect on whether my function parameters can be owned or borrowed. Here is an example: I am writing some GeoJson parsing code, and I want to use this convenience function from a 3rd party crate:
pub fn from_feature<T>(feature: Feature) -> GeometryCollection<T> where
T: Num + NumCast + PartialOrd + Copy + Float
Basically from_feature
takes a geojson:: Feature and converts it into a geo:: GeometryCollection. Because it takes ownership of the feature
, that requirement seems to bleed upwards and effects my function signature. In this example I want to create a Vec of these GeometryWithBounds structs. The fn is unfinished, but it compiles:
struct GeometryWithBounds<T>
where
T: CoordinateType,
{
geometry: Geometry<T>,
bounding_rect: Option<Rect<T>>,
}
fn extract_geometries_and_bounds(
feature_collection: geojson::FeatureCollection, //*** I have to take ownership of the feature_collection
) -> Vec<GeometryWithBounds<f64>> {
feature_collection
.features
.into_iter()
.flat_map(|feature| {
let geometry_collection = from_feature::<f64>(feature); // *** Because of this
geometry_collection
.into_iter()
.map(|geometry| match &geometry {
Geometry::Polygon(polygon) => Some(GeometryWithBounds {
geometry,
bounding_rect: None,
}),
_ => None,
})
})
.filter_map(|some_geometry| some_geometry)
.collect()
}
What if I wanted to change my function signature to take a reference to the feature_collection instead of owned?
fn extract_geometries_and_bounds_borrow(
feature_collection: &geojson::FeatureCollection, // *** might be nice to take a reference
) -> Vec<GeometryWithBounds<f64>> {
(&feature_collection.features)
.iter()
.flat_map(|feature| {
let geometry_collection = from_feature::<f64>(feature); // *** cannot get past this api call
...
Similarly, what if I wanted my struct to have references instead of owned:
geometry: &Geometry<T>,
bounding_rect: Option<&Rect<T>>,
Is that simply not possible based on the rules of the ownership universe, or (more likely) as a beginner in Rust I just have not hit upon the right combination of syntax?
Is this common where your own function signatures are to a large degree dictated by what crates and libraries you are using inside of your functions?
Hopefully I am just confused, but would greatly appreciate any advice or if there are any articles written about when to make your fn take a reference, and when to make your fn take ownership, that would be most interesting.