Skip to content

Commit d3b07ee

Browse files
Merge #936
936: `no_std` support for `geo-types` r=frewsxcv a=wetheredge - [x] I agree to follow the project's [code of conduct](https://github.com/georust/geo/blob/main/CODE_OF_CONDUCT.md). - [x] I added an entry to `CHANGES.md` if knowledge of this change could be valuable to users. --- This is my take on `no_std` support. This adds a new `std` that behave similarly to `serde`'s. Rough overview of my changes: - For the most part, simply swapping `alloc` or `core` in for `std`. - Also added a second `doc(hidden)` public module (`_alloc`) to give macros access to `Vec` and `Box` even if the crate they are used from does not have `extern crate alloc`. This could be merged into the existing `private_utils`. It could also be dropped entirely, but that would require modifying the macros to reference `std` when that feature is enabled and the cleanest way I found to do that is still somewhat ugly: match on `()` with `cfg`'d branches. I've looked some at #426 and the main difference I see is that it adds `core-error` for the `Error` trait, while I've just put that behind the `std` feature. If that is preferred, I can add the dependency. --- I have also started working on `no_std` support in `geo`, but it's not quite as straight-forward, so I was keeping it for a second PR. fixes #422, partially supersedes #426 Co-authored-by: William Etheredge <me@wetheredge.com>
2 parents b559cc3 + 758f438 commit d3b07ee

File tree

16 files changed

+86
-42
lines changed

16 files changed

+86
-42
lines changed

.github/workflows/test.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ jobs:
7676
steps:
7777
- name: Checkout repository
7878
uses: actions/checkout@v2
79+
- run: rustup target add thumbv7em-none-eabihf
7980
- run: cargo check --all-targets --no-default-features
81+
- run: cargo check --lib --target thumbv7em-none-eabihf --no-default-features -F use-rstar_0_9,serde
8082
- run: cargo test --all-features
8183

8284
geo:

geo-types/CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* Return `DoubleEndedIterator` from `LineString::points` and `LineString::points_mut`
66
* <https://github.com/georust/geo/pull/951>
77
* POSSIBLY BREAKING: Minimum supported version of Rust (MSRV) is now 1.63
8+
* Add `no_std` compatibility when the new default `std` feature is disabled
9+
* <https://github.com/georust/geo/pull/936>
810

911
## 0.7.8
1012

geo-types/Cargo.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ rust-version = "1.63"
1111
edition = "2021"
1212

1313
[features]
14+
default = ["std"]
15+
std = ["approx/std", "num-traits/std", "serde/std"]
1416
# Prefer `use-rstar` feature rather than enabling rstar directly.
1517
# rstar integration relies on the optional approx crate, but implicit features cannot yet enable other features.
1618
# See: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#namespaced-features
@@ -20,12 +22,12 @@ use-rstar_0_8 = ["rstar_0_8", "approx"]
2022
use-rstar_0_9 = ["rstar_0_9", "approx"]
2123

2224
[dependencies]
23-
approx = { version = ">= 0.4.0, < 0.6.0", optional = true }
25+
approx = { version = ">= 0.4.0, < 0.6.0", optional = true, default-features = false }
2426
arbitrary = { version = "1.2.0", optional = true }
25-
num-traits = "0.2"
27+
num-traits = { version = "0.2", default-features = false, features = ["libm"] }
2628
rstar_0_8 = { package = "rstar", version = "0.8", optional = true }
2729
rstar_0_9 = { package = "rstar", version = "0.9", optional = true }
28-
serde = { version = "1", optional = true, features = ["derive"] }
30+
serde = { version = "1", optional = true, default-features = false, features = ["alloc", "derive"] }
2931

3032
[dev-dependencies]
3133
approx = ">= 0.4.0, < 0.6.0"

geo-types/src/error.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::fmt;
1+
use core::fmt;
22

33
#[derive(Debug)]
44
pub enum Error {
@@ -8,6 +8,7 @@ pub enum Error {
88
},
99
}
1010

11+
#[cfg(feature = "std")]
1112
impl std::error::Error for Error {}
1213

1314
impl fmt::Display for Error {
@@ -23,7 +24,8 @@ impl fmt::Display for Error {
2324
#[cfg(test)]
2425
mod test {
2526
use crate::{Geometry, Point, Rect};
26-
use std::convert::TryFrom;
27+
use alloc::string::ToString;
28+
use core::convert::TryFrom;
2729

2830
#[test]
2931
fn error_output() {

geo-types/src/geometry/coord.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ impl<T: CoordNum> Coord<T> {
100100
}
101101
}
102102

103-
use std::ops::{Add, Div, Mul, Neg, Sub};
103+
use core::ops::{Add, Div, Mul, Neg, Sub};
104104

105105
/// Negate a coordinate.
106106
///

geo-types/src/geometry/geometry_collection.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
use crate::{CoordNum, Geometry};
22

3+
use alloc::vec;
4+
use alloc::vec::Vec;
35
#[cfg(any(feature = "approx", test))]
46
use approx::{AbsDiffEq, RelativeEq};
5-
use std::iter::FromIterator;
6-
use std::ops::{Index, IndexMut};
7+
use core::iter::FromIterator;
8+
use core::ops::{Index, IndexMut};
79

810
/// A collection of [`Geometry`](enum.Geometry.html) types.
911
///
@@ -148,7 +150,7 @@ impl<T: CoordNum> IndexMut<usize> for GeometryCollection<T> {
148150
// structure helper for consuming iterator
149151
#[derive(Debug)]
150152
pub struct IntoIteratorHelper<T: CoordNum> {
151-
iter: ::std::vec::IntoIter<Geometry<T>>,
153+
iter: ::alloc::vec::IntoIter<Geometry<T>>,
152154
}
153155

154156
// implement the IntoIterator trait for a consuming iterator. Iteration will
@@ -178,7 +180,7 @@ impl<T: CoordNum> Iterator for IntoIteratorHelper<T> {
178180
// structure helper for non-consuming iterator
179181
#[derive(Debug)]
180182
pub struct IterHelper<'a, T: CoordNum> {
181-
iter: ::std::slice::Iter<'a, Geometry<T>>,
183+
iter: ::core::slice::Iter<'a, Geometry<T>>,
182184
}
183185

184186
// implement the IntoIterator trait for a non-consuming iterator. Iteration will
@@ -208,7 +210,7 @@ impl<'a, T: CoordNum> Iterator for IterHelper<'a, T> {
208210
// structure helper for mutable non-consuming iterator
209211
#[derive(Debug)]
210212
pub struct IterMutHelper<'a, T: CoordNum> {
211-
iter: ::std::slice::IterMut<'a, Geometry<T>>,
213+
iter: ::core::slice::IterMut<'a, Geometry<T>>,
212214
}
213215

214216
// implement the IntoIterator trait for a mutable non-consuming iterator. Iteration will
@@ -323,6 +325,8 @@ where
323325

324326
#[cfg(test)]
325327
mod tests {
328+
use alloc::vec;
329+
326330
use crate::{GeometryCollection, Point};
327331

328332
#[test]

geo-types/src/geometry/line_string.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
use approx::{AbsDiffEq, RelativeEq};
33

44
use crate::{Coord, CoordNum, Line, Point, Triangle};
5-
use std::iter::FromIterator;
6-
use std::ops::{Index, IndexMut};
5+
use alloc::vec;
6+
use alloc::vec::Vec;
7+
use core::iter::FromIterator;
8+
use core::ops::{Index, IndexMut};
79

810
/// An ordered collection of two or more [`Coord`]s, representing a
911
/// path between locations.
@@ -136,7 +138,7 @@ pub struct LineString<T: CoordNum = f64>(pub Vec<Coord<T>>);
136138

137139
/// A [`Point`] iterator returned by the `points` method
138140
#[derive(Debug)]
139-
pub struct PointsIter<'a, T: CoordNum + 'a>(::std::slice::Iter<'a, Coord<T>>);
141+
pub struct PointsIter<'a, T: CoordNum + 'a>(::core::slice::Iter<'a, Coord<T>>);
140142

141143
impl<'a, T: CoordNum> Iterator for PointsIter<'a, T> {
142144
type Item = Point<T>;
@@ -164,7 +166,7 @@ impl<'a, T: CoordNum> DoubleEndedIterator for PointsIter<'a, T> {
164166

165167
/// A [`Coord`] iterator used by the `into_iter` method on a [`LineString`]
166168
#[derive(Debug)]
167-
pub struct CoordinatesIter<'a, T: CoordNum + 'a>(::std::slice::Iter<'a, Coord<T>>);
169+
pub struct CoordinatesIter<'a, T: CoordNum + 'a>(::core::slice::Iter<'a, Coord<T>>);
168170

169171
impl<'a, T: CoordNum> Iterator for CoordinatesIter<'a, T> {
170172
type Item = &'a Coord<T>;
@@ -358,7 +360,7 @@ impl<T: CoordNum, IC: Into<Coord<T>>> FromIterator<IC> for LineString<T> {
358360
/// Iterate over all the [`Coord`]s in this [`LineString`].
359361
impl<T: CoordNum> IntoIterator for LineString<T> {
360362
type Item = Coord<T>;
361-
type IntoIter = ::std::vec::IntoIter<Coord<T>>;
363+
type IntoIter = ::alloc::vec::IntoIter<Coord<T>>;
362364

363365
fn into_iter(self) -> Self::IntoIter {
364366
self.0.into_iter()
@@ -377,9 +379,9 @@ impl<'a, T: CoordNum> IntoIterator for &'a LineString<T> {
377379
/// Mutably iterate over all the [`Coord`]s in this [`LineString`]
378380
impl<'a, T: CoordNum> IntoIterator for &'a mut LineString<T> {
379381
type Item = &'a mut Coord<T>;
380-
type IntoIter = ::std::slice::IterMut<'a, Coord<T>>;
382+
type IntoIter = ::core::slice::IterMut<'a, Coord<T>>;
381383

382-
fn into_iter(self) -> ::std::slice::IterMut<'a, Coord<T>> {
384+
fn into_iter(self) -> ::core::slice::IterMut<'a, Coord<T>> {
383385
self.0.iter_mut()
384386
}
385387
}
@@ -534,14 +536,15 @@ mod test {
534536
#[test]
535537
fn test_exact_size() {
536538
// see https://github.com/georust/geo/issues/762
537-
let ls = LineString::new(vec![coord! { x: 0., y: 0. }, coord! { x: 10., y: 0. }]);
539+
let first = coord! { x: 0., y: 0. };
540+
let ls = LineString::new(vec![first, coord! { x: 10., y: 0. }]);
538541

539542
// reference to force the `impl IntoIterator for &LineString` impl, giving a `CoordinatesIter`
540543
for c in (&ls).into_iter().rev().skip(1).rev() {
541-
println!("{:?}", c);
544+
assert_eq!(&first, c);
542545
}
543546
for p in ls.points().rev().skip(1).rev() {
544-
println!("{:?}", p);
547+
assert_eq!(Point::from(first), p);
545548
}
546549
}
547550

geo-types/src/geometry/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use crate::{CoordNum, Error};
2929
#[cfg(any(feature = "approx", test))]
3030
use approx::{AbsDiffEq, RelativeEq};
3131
use core::any::type_name;
32-
use std::convert::TryFrom;
32+
use core::convert::TryFrom;
3333

3434
/// An enum representing any possible geometry type.
3535
///

geo-types/src/geometry/multi_line_string.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use crate::{CoordNum, LineString};
22

3+
use alloc::vec;
4+
use alloc::vec::Vec;
35
#[cfg(any(feature = "approx", test))]
46
use approx::{AbsDiffEq, RelativeEq};
5-
use std::iter::FromIterator;
7+
use core::iter::FromIterator;
68

79
/// A collection of
810
/// [`LineString`s](line_string/struct.LineString.html). Can
@@ -81,7 +83,7 @@ impl<T: CoordNum, ILS: Into<LineString<T>>> FromIterator<ILS> for MultiLineStrin
8183

8284
impl<T: CoordNum> IntoIterator for MultiLineString<T> {
8385
type Item = LineString<T>;
84-
type IntoIter = ::std::vec::IntoIter<LineString<T>>;
86+
type IntoIter = ::alloc::vec::IntoIter<LineString<T>>;
8587

8688
fn into_iter(self) -> Self::IntoIter {
8789
self.0.into_iter()
@@ -90,7 +92,7 @@ impl<T: CoordNum> IntoIterator for MultiLineString<T> {
9092

9193
impl<'a, T: CoordNum> IntoIterator for &'a MultiLineString<T> {
9294
type Item = &'a LineString<T>;
93-
type IntoIter = ::std::slice::Iter<'a, LineString<T>>;
95+
type IntoIter = ::alloc::slice::Iter<'a, LineString<T>>;
9496

9597
fn into_iter(self) -> Self::IntoIter {
9698
(self.0).iter()
@@ -99,7 +101,7 @@ impl<'a, T: CoordNum> IntoIterator for &'a MultiLineString<T> {
99101

100102
impl<'a, T: CoordNum> IntoIterator for &'a mut MultiLineString<T> {
101103
type Item = &'a mut LineString<T>;
102-
type IntoIter = ::std::slice::IterMut<'a, LineString<T>>;
104+
type IntoIter = ::alloc::slice::IterMut<'a, LineString<T>>;
103105

104106
fn into_iter(self) -> Self::IntoIter {
105107
(self.0).iter_mut()

geo-types/src/geometry/multi_point.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ use crate::{CoordNum, Point};
33
#[cfg(any(feature = "approx", test))]
44
use approx::{AbsDiffEq, RelativeEq};
55

6-
use std::iter::FromIterator;
6+
use alloc::vec;
7+
use alloc::vec::Vec;
8+
use core::iter::FromIterator;
79

810
/// A collection of [`Point`s](struct.Point.html). Can
911
/// be created from a `Vec` of `Point`s, or from an
@@ -58,7 +60,7 @@ impl<T: CoordNum, IP: Into<Point<T>>> FromIterator<IP> for MultiPoint<T> {
5860
/// Iterate over the `Point`s in this `MultiPoint`.
5961
impl<T: CoordNum> IntoIterator for MultiPoint<T> {
6062
type Item = Point<T>;
61-
type IntoIter = ::std::vec::IntoIter<Point<T>>;
63+
type IntoIter = ::alloc::vec::IntoIter<Point<T>>;
6264

6365
fn into_iter(self) -> Self::IntoIter {
6466
self.0.into_iter()
@@ -67,7 +69,7 @@ impl<T: CoordNum> IntoIterator for MultiPoint<T> {
6769

6870
impl<'a, T: CoordNum> IntoIterator for &'a MultiPoint<T> {
6971
type Item = &'a Point<T>;
70-
type IntoIter = ::std::slice::Iter<'a, Point<T>>;
72+
type IntoIter = ::alloc::slice::Iter<'a, Point<T>>;
7173

7274
fn into_iter(self) -> Self::IntoIter {
7375
(self.0).iter()
@@ -76,7 +78,7 @@ impl<'a, T: CoordNum> IntoIterator for &'a MultiPoint<T> {
7678

7779
impl<'a, T: CoordNum> IntoIterator for &'a mut MultiPoint<T> {
7880
type Item = &'a mut Point<T>;
79-
type IntoIter = ::std::slice::IterMut<'a, Point<T>>;
81+
type IntoIter = ::alloc::slice::IterMut<'a, Point<T>>;
8082

8183
fn into_iter(self) -> Self::IntoIter {
8284
(self.0).iter_mut()

0 commit comments

Comments
 (0)