Skip to content

Commit 1a91033

Browse files
tormolThomas Bahn
and
Thomas Bahn
authored
Add alloc feature (#75)
* Add alloc feature which enables AsciiStriing but not Error or CStr * Update src/ascii_str.rs Co-authored-by: Thomas Bahn <thomas@thomas-bahn.net>
1 parent 92512d6 commit 1a91033

File tree

5 files changed

+60
-29
lines changed

5 files changed

+60
-29
lines changed

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ serde_test = { version = "1.0", optional = true }
1414

1515
[features]
1616
default = ["std"]
17-
std = []
17+
std = ["alloc"]
18+
alloc = []
1819

1920
[[test]]
2021
name = "tests"

README.md

+10-7
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,20 @@ ascii = "1.0"
1717

1818
Most of `AsciiChar` and `AsciiStr` can be used without `std` by disabling the
1919
default features. The owned string type `AsciiString` and the conversion trait
20-
`IntoAsciiString` as well as all methods referring to these types and
21-
`CStr` and `CString` are unavailable.
22-
The `Error` trait is also unavailable, but `description()` is made
23-
available as an inherent method for `ToAsciiCharError` and `AsAsciiStrError`.
20+
`IntoAsciiString` as well as all methods referring to these types can be
21+
re-enabled by enabling the `alloc` feature.
2422

25-
To use the `ascii` crate in `core`-only mode in your cargo project just add the
26-
following dependency declaration in `Cargo.toml`:
23+
Methods referring to `CStr` and `CString` are also unavailable.
24+
The `Error` trait also only exists in `std`, but `description()` is made
25+
available as an inherent method for `ToAsciiCharError` and `AsAsciiStrError`
26+
in `#![no_std]`-mode.
27+
28+
To use the `ascii` crate in `#![no_std]` mode in your cargo project,
29+
just add the following dependency declaration in `Cargo.toml`:
2730

2831
```toml
2932
[dependencies]
30-
ascii = { version = "1.0", default-features = false }
33+
ascii = { version = "1.0", default-features = false, features = ["alloc"] }
3134
```
3235

3336
## Minimum supported Rust version

src/ascii_str.rs

+17-9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
#[cfg(feature = "alloc")]
2+
use alloc::borrow::ToOwned;
3+
#[cfg(feature = "alloc")]
4+
use alloc::boxed::Box;
15
use core::fmt;
26
use core::ops::{Index, IndexMut};
37
use core::ops::{Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive};
@@ -8,7 +12,7 @@ use std::error::Error;
812
use std::ffi::CStr;
913

1014
use ascii_char::AsciiChar;
11-
#[cfg(feature = "std")]
15+
#[cfg(feature = "alloc")]
1216
use ascii_string::AsciiString;
1317

1418
/// [`AsciiStr`] represents a byte or string slice that only contains ASCII characters.
@@ -77,7 +81,7 @@ impl AsciiStr {
7781
}
7882

7983
/// Copies the content of this `AsciiStr` into an owned `AsciiString`.
80-
#[cfg(feature = "std")]
84+
#[cfg(feature = "alloc")]
8185
#[must_use]
8286
pub fn to_ascii_string(&self) -> AsciiString {
8387
AsciiString::from(self.slice.to_vec())
@@ -283,7 +287,7 @@ impl AsciiStr {
283287
}
284288

285289
/// Returns a copy of this string where letters 'a' to 'z' are mapped to 'A' to 'Z'.
286-
#[cfg(feature = "std")]
290+
#[cfg(feature = "alloc")]
287291
#[must_use]
288292
pub fn to_ascii_uppercase(&self) -> AsciiString {
289293
let mut ascii_string = self.to_ascii_string();
@@ -292,7 +296,7 @@ impl AsciiStr {
292296
}
293297

294298
/// Returns a copy of this string where letters 'A' to 'Z' are mapped to 'a' to 'z'.
295-
#[cfg(feature = "std")]
299+
#[cfg(feature = "alloc")]
296300
#[must_use]
297301
pub fn to_ascii_lowercase(&self) -> AsciiString {
298302
let mut ascii_string = self.to_ascii_string();
@@ -336,7 +340,7 @@ impl_partial_eq! {str}
336340
impl_partial_eq! {[u8]}
337341
impl_partial_eq! {[AsciiChar]}
338342

339-
#[cfg(feature = "std")]
343+
#[cfg(feature = "alloc")]
340344
impl ToOwned for AsciiStr {
341345
type Owned = AsciiString;
342346

@@ -391,7 +395,7 @@ impl<'a> From<&'a mut [AsciiChar]> for &'a mut AsciiStr {
391395
unsafe { &mut *ptr }
392396
}
393397
}
394-
#[cfg(feature = "std")]
398+
#[cfg(feature = "alloc")]
395399
impl From<Box<[AsciiChar]>> for Box<AsciiStr> {
396400
#[inline]
397401
fn from(owned: Box<[AsciiChar]>) -> Box<AsciiStr> {
@@ -451,7 +455,7 @@ impl<'a> From<&'a AsciiStr> for &'a str {
451455
}
452456
macro_rules! widen_box {
453457
($wider: ty) => {
454-
#[cfg(feature = "std")]
458+
#[cfg(feature = "alloc")]
455459
impl From<Box<AsciiStr>> for Box<$wider> {
456460
#[inline]
457461
fn from(owned: Box<AsciiStr>) -> Box<$wider> {
@@ -1218,6 +1222,10 @@ impl AsAsciiStr for CStr {
12181222
#[cfg(test)]
12191223
mod tests {
12201224
use super::{AsAsciiStr, AsAsciiStrError, AsMutAsciiStr, AsciiStr};
1225+
#[cfg(feature = "alloc")]
1226+
use alloc::string::{String, ToString};
1227+
#[cfg(feature = "alloc")]
1228+
use alloc::vec::Vec;
12211229
use AsciiChar;
12221230

12231231
/// Ensures that common types, `str`, `[u8]`, `AsciiStr` and their
@@ -1330,7 +1338,7 @@ mod tests {
13301338
}
13311339

13321340
#[test]
1333-
#[cfg(feature = "std")]
1341+
#[cfg(feature = "alloc")]
13341342
fn as_mut_ascii_str() {
13351343
macro_rules! err {{$i:expr} => {Err(AsAsciiStrError($i))}}
13361344
let mut s: String = "abčd".to_string();
@@ -1409,7 +1417,7 @@ mod tests {
14091417
}
14101418

14111419
#[test]
1412-
#[cfg(feature = "std")]
1420+
#[cfg(feature = "alloc")]
14131421
fn to_ascii_case() {
14141422
let bytes = ([b'a', b'@', b'A'], [b'A', b'@', b'a']);
14151423
let a = bytes.0.as_ascii_str().unwrap();

src/ascii_string.rs

+26-10
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1-
use std::any::Any;
2-
use std::borrow::{Borrow, BorrowMut, Cow};
1+
use alloc::borrow::{Borrow, BorrowMut, Cow, ToOwned};
2+
use alloc::fmt;
3+
use alloc::string::String;
4+
use alloc::vec::Vec;
5+
#[cfg(feature = "std")]
6+
use core::any::Any;
7+
use core::iter::FromIterator;
8+
use core::mem;
9+
use core::ops::{Add, AddAssign, Deref, DerefMut, Index, IndexMut};
10+
use core::str::FromStr;
11+
#[cfg(feature = "std")]
312
use std::error::Error;
13+
#[cfg(feature = "std")]
414
use std::ffi::{CStr, CString};
5-
use std::iter::FromIterator;
6-
use std::ops::{Add, AddAssign, Deref, DerefMut, Index, IndexMut};
7-
use std::str::FromStr;
8-
use std::{fmt, mem};
915

1016
use ascii_char::AsciiChar;
1117
use ascii_str::{AsAsciiStr, AsAsciiStrError, AsciiStr};
@@ -699,6 +705,7 @@ impl<O> fmt::Display for FromAsciiError<O> {
699705
fmt::Display::fmt(&self.error, fmtr)
700706
}
701707
}
708+
#[cfg(feature = "std")]
702709
impl<O: Any> Error for FromAsciiError<O> {
703710
#[inline]
704711
#[allow(deprecated)] // TODO: Remove deprecation once the earliest version we support deprecates this method.
@@ -799,7 +806,8 @@ impl_into_ascii_string! {String}
799806
impl_into_ascii_string! {'a, &'a str}
800807

801808
/// # Notes
802-
/// The trailing null byte `CString` has will be removed during this conversion
809+
/// The trailing null byte `CString` has will be removed during this conversion.
810+
#[cfg(feature = "std")]
803811
impl IntoAsciiString for CString {
804812
#[inline]
805813
unsafe fn into_ascii_string_unchecked(self) -> AsciiString {
@@ -826,6 +834,7 @@ impl IntoAsciiString for CString {
826834
}
827835

828836
/// Note that the trailing null byte will be removed in the conversion.
837+
#[cfg(feature = "std")]
829838
impl<'a> IntoAsciiString for &'a CStr {
830839
#[inline]
831840
unsafe fn into_ascii_string_unchecked(self) -> AsciiString {
@@ -885,9 +894,14 @@ where
885894

886895
#[cfg(test)]
887896
mod tests {
888-
use super::{AsciiString, IntoAsciiString};
897+
use super::AsciiString;
898+
#[cfg(feature = "std")]
899+
use super::IntoAsciiString;
900+
use alloc::str::FromStr;
901+
use alloc::string::{String, ToString};
902+
use alloc::vec::Vec;
903+
#[cfg(feature = "std")]
889904
use std::ffi::CString;
890-
use std::str::FromStr;
891905
use AsciiChar;
892906

893907
#[test]
@@ -912,6 +926,7 @@ mod tests {
912926
}
913927

914928
#[test]
929+
#[cfg(feature = "std")]
915930
fn from_cstring() {
916931
let cstring = CString::new("baz").unwrap();
917932
let ascii_str = cstring.clone().into_ascii_string().unwrap();
@@ -932,6 +947,7 @@ mod tests {
932947
}
933948

934949
#[test]
950+
#[cfg(feature = "std")]
935951
fn fmt_ascii_string() {
936952
let s = "abc".to_string().into_ascii_string().unwrap();
937953
assert_eq!(format!("{}", s), "abc".to_string());
@@ -940,7 +956,7 @@ mod tests {
940956

941957
#[test]
942958
fn write_fmt() {
943-
use std::{fmt, str};
959+
use alloc::{fmt, str};
944960

945961
let mut s0 = AsciiString::new();
946962
fmt::write(&mut s0, format_args!("Hello World")).unwrap();

src/lib.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@
5454
// In preparation for feature `unsafe_block_in_unsafe_fn` (https://github.com/rust-lang/rust/issues/71668)
5555
#![allow(unused_unsafe)]
5656

57+
#[cfg(feature = "alloc")]
58+
#[cfg_attr(test, macro_use)]
59+
extern crate alloc;
5760
#[cfg(feature = "std")]
5861
extern crate core;
5962

@@ -65,7 +68,7 @@ extern crate serde_test;
6568

6669
mod ascii_char;
6770
mod ascii_str;
68-
#[cfg(feature = "std")]
71+
#[cfg(feature = "alloc")]
6972
mod ascii_string;
7073
mod free_functions;
7174
#[cfg(feature = "serde")]
@@ -74,6 +77,6 @@ mod serialization;
7477
pub use ascii_char::{AsciiChar, ToAsciiChar, ToAsciiCharError};
7578
pub use ascii_str::{AsAsciiStr, AsAsciiStrError, AsMutAsciiStr, AsciiStr};
7679
pub use ascii_str::{Chars, CharsMut, CharsRef};
77-
#[cfg(feature = "std")]
80+
#[cfg(feature = "alloc")]
7881
pub use ascii_string::{AsciiString, FromAsciiError, IntoAsciiString};
7982
pub use free_functions::{caret_decode, caret_encode};

0 commit comments

Comments
 (0)