diff --git a/Cargo.toml b/Cargo.toml index bdab3e2..fbea65e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,9 +11,9 @@ repository = "https://github.com/multiformats/rust-multibase" keywords = ["ipld", "ipfs", "multihash", "multibase", "cid"] [dependencies] -base-x = "0.2" -data-encoding = "2.2" -data-encoding-macro = "0.1.8" +base-x = { git = "https://github.com/whalelephant/base-x-rs", branch = "no_std", default-features = false } +data-encoding = { version = "2.3", default-features = false, features = ["alloc"] } +lazy_static = { features = ["spin_no_std"], version = "1.4.0" } [dev-dependencies] criterion = "0.3" @@ -25,3 +25,7 @@ harness = false [workspace] members = ["cli"] + +[features] +default = ["std"] +std = [] \ No newline at end of file diff --git a/src/base.rs b/src/base.rs index 467bc6e..d06ebd7 100644 --- a/src/base.rs +++ b/src/base.rs @@ -1,6 +1,9 @@ use crate::error::{Error, Result}; use crate::impls::*; +#[cfg(not(feature = "std"))] +use alloc::{string::String, vec::Vec}; + macro_rules! build_base_enum { ( $(#[$attr:meta] $code:expr => $base:ident,)* ) => { /// List of types currently supported in the multibase spec. diff --git a/src/encoding.rs b/src/encoding.rs index 9d8e11f..d9635ae 100644 --- a/src/encoding.rs +++ b/src/encoding.rs @@ -1,15 +1,58 @@ -use data_encoding::Encoding; -use data_encoding_macro::{internal_new_encoding, new_encoding}; - -// Base2 (alphabet: 01) -pub const BASE2: Encoding = new_encoding! { - symbols: "01", -}; - -// Base8 (alphabet: 01234567) -pub const BASE8: Encoding = new_encoding! { - symbols: "01234567", -}; +use data_encoding::{Encoding, Specification}; +use lazy_static::lazy_static; + +lazy_static! { + // Base2 (alphabet: 01) + pub static ref BASE2: Encoding = { + let mut spec = Specification::new(); + spec.symbols.push_str("01"); + spec.encoding().unwrap() + }; + + // Base8 (alphabet: 01234567) + pub static ref BASE8: Encoding = { + let mut spec = Specification::new(); + spec.symbols.push_str("01234567"); + spec.encoding().unwrap() + }; + + // Base32, rfc4648 no padding (alphabet: abcdefghijklmnopqrstuvwxyz234567). + pub static ref BASE32_NOPAD_LOWER: Encoding = { + let mut spec = Specification::new(); + spec.symbols.push_str("abcdefghijklmnopqrstuvwxyz234567"); + spec.encoding().unwrap() + }; + + // Base32, rfc4648 with padding (alphabet: abcdefghijklmnopqrstuvwxyz234567). + pub static ref BASE32_PAD_LOWER: Encoding = { + let mut spec = Specification::new(); + spec.symbols.push_str("abcdefghijklmnopqrstuvwxyz234567"); + spec.padding = Some('='); + spec.encoding().unwrap() + }; + + // Base32hex, rfc4648 no padding (alphabet: 0123456789abcdefghijklmnopqrstuv). + pub static ref BASE32HEX_NOPAD_LOWER: Encoding = { + let mut spec = Specification::new(); + spec.symbols.push_str("0123456789abcdefghijklmnopqrstuv"); + spec.encoding().unwrap() + }; + + // Base32hex, rfc4648 with padding (alphabet: 0123456789abcdefghijklmnopqrstuv). + pub static ref BASE32HEX_PAD_LOWER: Encoding = { + let mut spec = Specification::new(); + spec.symbols.push_str("0123456789abcdefghijklmnopqrstuv"); + spec.padding = Some('='); + spec.encoding().unwrap() + }; + + // z-base-32 (used by Tahoe-LAFS) (alphabet: ybndrfg8ejkmcpqxot1uwisza345h769). + pub static ref BASE32Z: Encoding = { + let mut spec = Specification::new(); + spec.symbols.push_str("ybndrfg8ejkmcpqxot1uwisza345h769"); + spec.encoding().unwrap() + }; +} /// Base10 (alphabet: 0123456789) pub const BASE10: &str = "0123456789"; @@ -20,45 +63,18 @@ pub const BASE16_LOWER: Encoding = data_encoding::HEXLOWER; // Base16 upper hexadecimal (alphabet: 0123456789ABCDEF). pub const BASE16_UPPER: Encoding = data_encoding::HEXUPPER; -// Base32, rfc4648 no padding (alphabet: abcdefghijklmnopqrstuvwxyz234567). -pub const BASE32_NOPAD_LOWER: Encoding = new_encoding! { - symbols: "abcdefghijklmnopqrstuvwxyz234567", -}; - // Base32, rfc4648 no padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZ234567). pub const BASE32_NOPAD_UPPER: Encoding = data_encoding::BASE32_NOPAD; -// Base32, rfc4648 with padding (alphabet: abcdefghijklmnopqrstuvwxyz234567). -pub const BASE32_PAD_LOWER: Encoding = new_encoding! { - symbols: "abcdefghijklmnopqrstuvwxyz234567", - padding: '=', -}; - // Base32, rfc4648 with padding (alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZ234567). pub const BASE32_PAD_UPPER: Encoding = data_encoding::BASE32; -// Base32hex, rfc4648 no padding (alphabet: 0123456789abcdefghijklmnopqrstuv). -pub const BASE32HEX_NOPAD_LOWER: Encoding = new_encoding! { - symbols: "0123456789abcdefghijklmnopqrstuv", -}; - // Base32hex, rfc4648 no padding (alphabet: 0123456789ABCDEFGHIJKLMNOPQRSTUV). pub const BASE32HEX_NOPAD_UPPER: Encoding = data_encoding::BASE32HEX_NOPAD; -// Base32hex, rfc4648 with padding (alphabet: 0123456789abcdefghijklmnopqrstuv). -pub const BASE32HEX_PAD_LOWER: Encoding = new_encoding! { - symbols: "0123456789abcdefghijklmnopqrstuv", - padding: '=', -}; - /// Base32hex, rfc4648 with padding (alphabet: 0123456789ABCDEFGHIJKLMNOPQRSTUV). pub const BASE32HEX_PAD_UPPER: Encoding = data_encoding::BASE32HEX; -// z-base-32 (used by Tahoe-LAFS) (alphabet: ybndrfg8ejkmcpqxot1uwisza345h769). -pub const BASE32Z: Encoding = new_encoding! { - symbols: "ybndrfg8ejkmcpqxot1uwisza345h769", -}; - // Base58 Flickr's alphabet for creating short urls from photo ids. pub const BASE58_FLICKR: &str = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"; diff --git a/src/error.rs b/src/error.rs index a108578..3444339 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,7 @@ -use std::{error, fmt}; +#[cfg(not(feature = "std"))] +use core as std; + +use std::fmt; /// Type alias to use this library's [`Error`] type in a `Result`. pub type Result = std::result::Result; @@ -21,7 +24,8 @@ impl fmt::Display for Error { } } -impl error::Error for Error {} +#[cfg(feature = "std")] +impl std::error::Error for Error {} impl From for Error { fn from(_: base_x::DecodeError) -> Self { diff --git a/src/impls.rs b/src/impls.rs index 69528a8..a7babb6 100644 --- a/src/impls.rs +++ b/src/impls.rs @@ -1,6 +1,9 @@ use crate::encoding; use crate::error::Result; +#[cfg(not(feature = "std"))] +use alloc::{string::String, vec::Vec}; + pub(crate) trait BaseCodec { /// Encode with the given byte slice. fn encode>(input: I) -> String; diff --git a/src/lib.rs b/src/lib.rs index 01ca939..357d18b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,12 @@ //! # multibase //! //! Implementation of [multibase](https://github.com/multiformats/multibase) in Rust. - +#![cfg_attr(not(feature = "std"), no_std)] #![deny(missing_docs)] +#[cfg(not(feature = "std"))] +extern crate alloc; + mod base; mod encoding; mod error; @@ -12,6 +15,9 @@ mod impls; pub use self::base::Base; pub use self::error::{Error, Result}; +#[cfg(not(feature = "std"))] +use alloc::{string::String, vec::Vec}; + /// Decode the base string. /// /// # Examples