diff --git a/Cargo.toml b/Cargo.toml index 54121b5..cff37c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,10 +9,14 @@ repository = "https://github.com/tjol/sprintf-rs" keywords = ["printf", "text", "string"] categories = ["template-engine", "wasm"] -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[features] +default = ["thiserror/std", "num-traits/std"] +no_std = ["num-traits/libm"] [dependencies] -thiserror = "2.0" +cfg-if = "1.0" +thiserror = { version = "2.0", default-features = false } +num-traits = { version = "0.2", default-features = false } [dev-dependencies] libc = "0.2" diff --git a/README.md b/README.md index 32c0a08..74b8afd 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ This crate was created out of a desire to provide C printf-style formatting in a WASM program, where there is no libc. -**Note:** *You're probably better off using standard Rust string formatting -instead of this crate unless you specificaly need printf compatibility.* +**Note:** _You're probably better off using standard Rust string formatting +instead of this crate unless you specificaly need printf compatibility._ This crate implements a dynamically type-checked function `vsprintf` and macro `sprintf!`. @@ -20,5 +20,5 @@ assert_eq!(s, "3 + 9 = 12\n"); ``` `libc` is a dev dependency as it is used in the tests to compare results. This -crate depends on `std` for string formatting, memory allocation, and -floating-point maths. +crate depends on `std` by default, but the default features can be disabled and +the `no_std` feature can be enabled as an alternative. diff --git a/src/format.rs b/src/format.rs index 10b82f1..b11de01 100644 --- a/src/format.rs +++ b/src/format.rs @@ -1,6 +1,7 @@ -use std::convert::{TryFrom, TryInto}; -use std::ffi::{CStr, CString}; +use core::convert::{TryFrom, TryInto}; +use core::ffi::CStr; +use crate::compat::*; use crate::{ parser::{ConversionSpecifier, ConversionType, NumericParam}, PrintfError, Result, diff --git a/src/lib.rs b/src/lib.rs index cf45a4f..2bcdf30 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +#![cfg_attr(feature = "no_std", no_std)] + //! Libc s(n)printf clone written in Rust, so you can use printf-style //! formatting without a libc (e.g. in WebAssembly). //! @@ -25,11 +27,34 @@ use thiserror::Error; mod format; pub mod parser; +use compat::*; pub use format::Printf; use parser::{parse_format_string, FormatElement}; #[doc(hidden)] pub use parser::{ConversionSpecifier, ConversionType, NumericParam}; +pub(crate) mod compat { + cfg_if::cfg_if! { + if #[cfg(feature = "no_std")] { + extern crate alloc; + + pub use alloc::ffi::CString; + pub use alloc::format; + pub use alloc::string::String; + pub use alloc::borrow::ToOwned; + pub use alloc::vec::Vec; + + pub use num_traits::Float; + } else { + pub use std::ffi::CString; + pub use std::format; + pub use std::string::String; + pub use std::borrow::ToOwned; + pub use std::vec::Vec; + } + } +} + /// Error type #[derive(Debug, Clone, Copy, Error, PartialEq, Eq)] pub enum PrintfError { @@ -50,7 +75,7 @@ pub enum PrintfError { Unknown, } -pub type Result = std::result::Result; +pub type Result = core::result::Result; /// Format a string. (Roughly equivalent to `vsnprintf` or `vasprintf` in C) /// diff --git a/src/parser.rs b/src/parser.rs index d5c29b8..e74485c 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,5 +1,6 @@ //! Parse printf format strings +use crate::compat::*; use crate::{PrintfError, Result}; /// A part of a format string: either a string of characters to be included