Skip to content

Commit dcaceba

Browse files
authored
Merge pull request #7 from jelacious/no_std_ipaddr
`no_std` support
2 parents f0a0536 + 86e15b6 commit dcaceba

File tree

10 files changed

+99
-58
lines changed

10 files changed

+99
-58
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
profile: minimal
1616
toolchain: nightly
1717
override: true
18-
- name: Test with no feature
18+
- name: Test with default features
1919
uses: actions-rs/cargo@v1
2020
with:
2121
command: test
@@ -28,7 +28,7 @@ jobs:
2828
uses: actions-rs/cargo@v1
2929
with:
3030
command: doc
31-
args: --no-deps --features ipv_future,rfc6874bis
31+
args: --no-deps --features ipv_future,rfc6874bis,std
3232
- name: Deploy docs
3333
uses: peaceiris/actions-gh-pages@v3
3434
with:

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ categories = ["encoding", "parser-implementations"]
1515
bitflags = "1.3.2"
1616

1717
[features]
18+
default = ["std"]
1819
ipv_future = []
1920
rfc6874bis = []
2021
unstable = []
22+
std = []
2123

2224
[package.metadata.docs.rs]
23-
features = ["ipv_future", "rfc6874bis"]
25+
features = ["ipv_future", "rfc6874bis", "std"]
2426

2527
# Commented out to reduce compile time.
2628

src/enc/estring.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
use std::{borrow::Borrow, fmt, hash, marker::PhantomData, ops::Deref};
1+
use alloc::string::String;
2+
use core::{borrow::Borrow, fmt, hash, marker::PhantomData, ops::Deref};
3+
4+
#[cfg(feature = "unstable")]
5+
use alloc::vec::Vec;
26

37
use super::{
48
encoder::Encoder,
@@ -341,7 +345,7 @@ impl<E: Encoder> Clone for EString<E> {
341345
impl<E: Encoder> fmt::Debug for EString<E> {
342346
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
343347
f.debug_struct("EString")
344-
.field("encoder", &std::any::type_name::<E>())
348+
.field("encoder", &core::any::type_name::<E>())
345349
.field("contents", &self.string)
346350
.finish()
347351
}

src/enc/imp.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ use super::table;
33
#[cfg(feature = "unstable")]
44
use super::table::Table;
55

6-
use std::{fmt, ptr};
6+
use alloc::vec::Vec;
7+
use core::{fmt, ptr};
78

89
#[cfg(feature = "unstable")]
9-
use std::{borrow::Cow, str};
10+
use alloc::{borrow::Cow, str, string::String};
1011

1112
/// Returns immediately with an encoding error.
1213
macro_rules! err {
@@ -57,6 +58,7 @@ impl EncodingError {
5758
}
5859
}
5960

61+
#[cfg(feature = "std")]
6062
impl std::error::Error for EncodingError {}
6163

6264
impl fmt::Display for EncodingError {
@@ -70,7 +72,7 @@ impl fmt::Display for EncodingError {
7072
}
7173
}
7274

73-
pub(crate) type Result<T, E = EncodingError> = std::result::Result<T, E>;
75+
pub(crate) type Result<T, E = EncodingError> = core::result::Result<T, E>;
7476

7577
#[cfg(feature = "unstable")]
7678
const fn gen_hex_table() -> [u8; 512] {

src/enc/mod.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,16 @@ pub fn validate<S: AsRef<[u8]> + ?Sized>(s: &S, table: &Table) -> Result<()> {
8989
}
9090
}
9191

92-
use std::{
92+
use alloc::{
9393
borrow::{self, Cow},
94+
string::{FromUtf8Error, String},
95+
vec::Vec,
96+
};
97+
use core::{
9498
fmt, hash,
9599
iter::FusedIterator,
96100
mem,
97101
str::{self, Utf8Error},
98-
string::FromUtf8Error,
99102
};
100103

101104
use crate::view::View;
@@ -275,7 +278,7 @@ impl EStr {
275278
/// assert_eq!(dec.to_str()?, "233");
276279
/// assert!(dec.decoded_any());
277280
/// assert_eq!(buf, b"233");
278-
/// # Ok::<_, std::str::Utf8Error>(())
281+
/// # Ok::<_, core::str::Utf8Error>(())
279282
/// ```
280283
#[cfg(feature = "unstable")]
281284
#[inline]
@@ -778,7 +781,7 @@ impl FusedIterator for SplitView<'_> {}
778781
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
779782
pub struct BufferTooSmallError(());
780783

781-
#[cfg(feature = "unstable")]
784+
#[cfg(all(feature = "unstable", feature = "std"))]
782785
impl std::error::Error for BufferTooSmallError {}
783786

784787
#[cfg(feature = "unstable")]
@@ -791,7 +794,8 @@ impl fmt::Display for BufferTooSmallError {
791794
#[cfg(feature = "unstable")]
792795
pub(crate) mod internal {
793796
use crate::enc::BufferTooSmallError;
794-
use std::{collections::TryReserveError, mem::MaybeUninit};
797+
use alloc::{collections::TryReserveError, string::String, vec::Vec};
798+
use core::mem::MaybeUninit;
795799

796800
pub trait AsMutVec {
797801
unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8>;

src/fmt.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::*;
2-
use std::fmt;
2+
use alloc::string::String;
3+
use core::fmt;
34

45
impl fmt::Display for ParseError {
56
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

src/internal.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
#![allow(missing_debug_implementations)]
22

3-
use std::{
3+
use alloc::{string::String, vec::Vec};
4+
use core::{
45
cell::Cell,
56
mem::MaybeUninit,
67
num::NonZeroU32,
78
ops::{Deref, DerefMut},
89
};
910

11+
#[cfg(feature = "std")]
12+
use std::net::{Ipv4Addr, Ipv6Addr};
13+
1014
use super::*;
1115
use bitflags::bitflags;
1216

@@ -231,15 +235,17 @@ pub struct AuthData {
231235

232236
#[derive(Clone, Copy)]
233237
pub union RawHostData {
238+
#[cfg(feature = "std")]
234239
pub ipv4_addr: Ipv4Addr,
235240
pub ipv6: Ipv6Data,
236241
#[cfg(feature = "ipv_future")]
237242
pub ipv_future_dot_i: u32,
238-
pub reg_name: (),
243+
pub none: (),
239244
}
240245

241246
#[derive(Clone, Copy)]
242247
pub struct Ipv6Data {
248+
#[cfg(feature = "std")]
243249
pub addr: Ipv6Addr,
244250
#[cfg(feature = "rfc6874bis")]
245251
pub zone_id_start: Option<NonZeroU32>,

src/lib.rs

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![warn(missing_debug_implementations, missing_docs, rust_2018_idioms)]
22
#![deny(unsafe_op_in_unsafe_fn)]
3+
#![cfg_attr(not(feature = "std"), no_std)]
34

45
//! A generic URI parser that strictly adheres to IETF [RFC 3986].
56
//!
@@ -9,11 +10,14 @@
910
//!
1011
//! # Feature flags
1112
//!
12-
//! All features are disabled by default. However, note that these features each
13-
//! alter the enum [`HostData`] in a backward incompatible way that could make it
13+
//! All features except `std` are disabled by default. Note that the last two features
14+
//! each alter the enum [`HostData`] in a backward incompatible way that could make it
1415
//! impossible for two crates that depend on different features of `fluent-uri` to
1516
//! be used together.
1617
//!
18+
//! - `std`: Enables `std` support. This includes [`Error`] implementations
19+
//! and `Ip{v4, v6}Addr` support in [`HostData`].
20+
//!
1721
//! - `ipv_future`: Enables the parsing of [IPvFuture] literal addresses,
1822
//! which fails with [`InvalidIpLiteral`] when disabled.
1923
//!
@@ -26,9 +30,12 @@
2630
//!
2731
//! This feature is based on the homonymous [draft] and is thus subject to change.
2832
//!
33+
//! [`Error`]: std::error::Error
2934
//! [IPvFuture]: https://datatracker.ietf.org/doc/html/rfc3986/#section-3.2.2
3035
//! [`InvalidIpLiteral`]: ParseErrorKind::InvalidIpLiteral
31-
//! [draft]: https://datatracker.ietf.org/doc/html/draft-ietf-6man-rfc6874bis-02
36+
//! [draft]: https://datatracker.ietf.org/doc/html/draft-ietf-6man-rfc6874bis-05
37+
38+
extern crate alloc;
3239

3340
/// Utilities for percent-encoding.
3441
pub mod enc;
@@ -41,13 +48,11 @@ pub use view::*;
4148
mod parser;
4249

4350
use crate::enc::{EStr, Split};
44-
use std::{
45-
marker::PhantomData,
46-
mem::ManuallyDrop,
47-
net::{Ipv4Addr, Ipv6Addr},
48-
ptr::NonNull,
49-
slice, str,
50-
};
51+
use alloc::{string::String, vec::Vec};
52+
use core::{iter::Iterator, marker::PhantomData, mem::ManuallyDrop, ptr::NonNull, slice, str};
53+
54+
#[cfg(feature = "std")]
55+
use std::net::{Ipv4Addr, Ipv6Addr};
5156

5257
mod internal;
5358
use internal::*;
@@ -90,9 +95,10 @@ impl ParseError {
9095
}
9196
}
9297

98+
#[cfg(feature = "std")]
9399
impl std::error::Error for ParseError {}
94100

95-
type Result<T, E = ParseError> = std::result::Result<T, E>;
101+
type Result<T, E = ParseError> = core::result::Result<T, E>;
96102

97103
#[cold]
98104
fn len_overflow() -> ! {
@@ -135,7 +141,7 @@ fn len_overflow() -> ! {
135141
/// # Examples
136142
///
137143
/// Create and convert between `Uri<&str>` and `Uri<String>`:
138-
///
144+
///
139145
/// ```
140146
/// use fluent_uri::Uri;
141147
///
@@ -882,19 +888,22 @@ impl<'i, 'o, T: Io<'i, 'o>> Host<T> {
882888
/// Returns the structured host data.
883889
#[inline]
884890
pub fn data(&'i self) -> HostData<'o> {
885-
let data = self.raw_data();
891+
let _data = self.raw_data();
886892
let tag = self.auth.uri.tag;
887893
// SAFETY: We only access the union after checking the tag.
888894
unsafe {
889895
if tag.contains(Tag::HOST_REG_NAME) {
890896
// SAFETY: The validation is done.
891897
return HostData::RegName(EStr::new_unchecked(self.as_str().as_bytes()));
892898
} else if tag.contains(Tag::HOST_IPV4) {
893-
return HostData::Ipv4(data.ipv4_addr);
899+
return HostData::Ipv4(
900+
#[cfg(feature = "std")]
901+
_data.ipv4_addr,
902+
);
894903
}
895904
#[cfg(feature = "ipv_future")]
896905
if !tag.contains(Tag::HOST_IPV6) {
897-
let dot_i = data.ipv_future_dot_i;
906+
let dot_i = _data.ipv_future_dot_i;
898907
let bounds = self.bounds();
899908
// SAFETY: The indexes are within bounds and the validation is done.
900909
return HostData::IpvFuture {
@@ -903,10 +912,11 @@ impl<'i, 'o, T: Io<'i, 'o>> Host<T> {
903912
};
904913
}
905914
HostData::Ipv6 {
906-
addr: data.ipv6.addr,
915+
#[cfg(feature = "std")]
916+
addr: _data.ipv6.addr,
907917
// SAFETY: The indexes are within bounds and the validation is done.
908918
#[cfg(feature = "rfc6874bis")]
909-
zone_id: data
919+
zone_id: _data
910920
.ipv6
911921
.zone_id_start
912922
.map(|start| self.auth.uri.slice(start.get(), self.bounds().1 - 1)),
@@ -919,10 +929,13 @@ impl<'i, 'o, T: Io<'i, 'o>> Host<T> {
919929
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
920930
pub enum HostData<'a> {
921931
/// An IPv4 address.
922-
Ipv4(Ipv4Addr),
932+
#[cfg_attr(not(feature = "std"), non_exhaustive)]
933+
Ipv4(#[cfg(feature = "std")] Ipv4Addr),
923934
/// An IPv6 address.
935+
#[cfg_attr(not(feature = "std"), non_exhaustive)]
924936
Ipv6 {
925937
/// The address.
938+
#[cfg(feature = "std")]
926939
addr: Ipv6Addr,
927940
/// An optional zone identifier.
928941
///

0 commit comments

Comments
 (0)