diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index e9797fd..6bdea5e 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,40 +1,22 @@ -# 0.21.0-beta.1 - -## Breaking changes - -- `FastPortable` was only meant to be an interim name, and shouldn't have shipped in 0.20. It is now `GeneralPurpose` to - make its intended usage more clear. -- `GeneralPurpose` and its config are now `pub use`'d in the `engine` module for convenience. -- Change a few `from()` functions to be `new()`. `from()` causes confusing compiler errors because of confusion - with `From::from`, and is a little misleading because some of those invocations are not very cheap as one would - usually expect from a `from` call. -- `encode*` and `decode*` top level functions are now methods on `Engine`. -- `DEFAULT_ENGINE` was replaced by `engine::general_purpose::STANDARD` -- Predefined engine consts `engine::general_purpose::{STANDARD, STANDARD_NO_PAD, URL_SAFE, URL_SAFE_NO_PAD}` - - These are `pub use`d into `engine` as well -- The `*_slice` decode/encode functions now return an error instead of panicking when the output slice is too small - - As part of this, there isn't now a public way to decode into a slice _exactly_ the size needed for inputs that - aren't multiples of 4 tokens. If adding up to 2 bytes to always be a multiple of 3 bytes for the decode buffer is - a problem, file an issue. +# 0.21.0 -## Other changes +(not yet released) -- `decoded_len_estimate()` is provided to make it easy to size decode buffers correctly. ## Migration ### Functions -| < 0.20 function | 0.21 equivalent | -|-------------------------|-----------------------------| -| `encode()` | `engine::STANDARD.encode()` | -| `encode_config()` | `engine.encode()` | -| `encode_config_buf()` | `engine.encode_string()` | -| `encode_config_slice()` | `engine.encode_slice()` | -| `decode()` | `engine::STANDARD.decode()` | -| `decode_config()` | `engine.decode()` | -| `decode_config_buf()` | `engine.decode_vec()` | -| `decode_config_slice()` | `engine.decode_slice()` | +| < 0.20 function | 0.21 equivalent | +|-------------------------|-------------------------------------------------------------------------------------| +| `encode()` | `engine::general_purpose::STANDARD.encode()` or `prelude::BASE64_STANDARD.encode()` | +| `encode_config()` | `engine.encode()` | +| `encode_config_buf()` | `engine.encode_string()` | +| `encode_config_slice()` | `engine.encode_slice()` | +| `decode()` | `engine::general_purpose::STANDARD.decode()` or `prelude::BASE64_STANDARD.decode()` | +| `decode_config()` | `engine.decode()` | +| `decode_config_buf()` | `engine.decode_vec()` | +| `decode_config_slice()` | `engine.decode_slice()` | The short-lived 0.20 functions were the 0.13 functions with `config` replaced with `engine`. @@ -55,6 +37,36 @@ precisely, see the following table. | URL_SAFE | URL_SAFE | true | Indifferent | | URL_SAFE_NO_PAD | URL_SAFE | false | Indifferent | + +# 0.21.0-beta.2 + +## Breaking changes + +- Re-exports of preconfigured engines in `engine` are removed in favor of `base64::prelude::...` that are better suited to those who wish to `use` the entire path to a name. + +# 0.21.0-beta.1 + +## Breaking changes + +- `FastPortable` was only meant to be an interim name, and shouldn't have shipped in 0.20. It is now `GeneralPurpose` to + make its intended usage more clear. +- `GeneralPurpose` and its config are now `pub use`'d in the `engine` module for convenience. +- Change a few `from()` functions to be `new()`. `from()` causes confusing compiler errors because of confusion + with `From::from`, and is a little misleading because some of those invocations are not very cheap as one would + usually expect from a `from` call. +- `encode*` and `decode*` top level functions are now methods on `Engine`. +- `DEFAULT_ENGINE` was replaced by `engine::general_purpose::STANDARD` +- Predefined engine consts `engine::general_purpose::{STANDARD, STANDARD_NO_PAD, URL_SAFE, URL_SAFE_NO_PAD}` + - These are `pub use`d into `engine` as well +- The `*_slice` decode/encode functions now return an error instead of panicking when the output slice is too small + - As part of this, there isn't now a public way to decode into a slice _exactly_ the size needed for inputs that + aren't multiples of 4 tokens. If adding up to 2 bytes to always be a multiple of 3 bytes for the decode buffer is + a problem, file an issue. + +## Other changes + +- `decoded_len_estimate()` is provided to make it easy to size decode buffers correctly. + # 0.20.0 ## Breaking changes diff --git a/benches/benchmarks.rs b/benches/benchmarks.rs index d79fb54..61d542f 100644 --- a/benches/benchmarks.rs +++ b/benches/benchmarks.rs @@ -3,7 +3,7 @@ extern crate criterion; use base64::{ display, - engine::{Engine, STANDARD}, + engine::{general_purpose::STANDARD, Engine}, write, }; use criterion::{black_box, Bencher, BenchmarkId, Criterion, Throughput}; diff --git a/fuzz/fuzzers/roundtrip.rs b/fuzz/fuzzers/roundtrip.rs index abb02a8..128c6b8 100644 --- a/fuzz/fuzzers/roundtrip.rs +++ b/fuzz/fuzzers/roundtrip.rs @@ -2,7 +2,7 @@ #[macro_use] extern crate libfuzzer_sys; extern crate base64; -use base64::{Engine as _, engine::STANDARD}; +use base64::{Engine as _, engine::general_purpose::STANDARD}; fuzz_target!(|data: &[u8]| { let encoded = STANDARD.encode(data); diff --git a/src/decode.rs b/src/decode.rs index ad7f10c..c0ad12c 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -1,4 +1,4 @@ -use crate::engine::{DecodeEstimate, Engine, STANDARD}; +use crate::engine::{general_purpose::STANDARD, DecodeEstimate, Engine}; #[cfg(any(feature = "alloc", feature = "std", test))] use alloc::vec::Vec; use core::fmt; diff --git a/src/display.rs b/src/display.rs index bb57038..fc292f1 100644 --- a/src/display.rs +++ b/src/display.rs @@ -1,8 +1,7 @@ //! Enables base64'd output anywhere you might use a `Display` implementation, like a format string. //! //! ``` -//! use base64::display::Base64Display; -//! use base64::engine::STANDARD; +//! use base64::{display::Base64Display, engine::general_purpose::STANDARD}; //! //! let data = vec![0x0, 0x1, 0x2, 0x3]; //! let wrapper = Base64Display::new(&data, &STANDARD); @@ -59,7 +58,7 @@ mod tests { chunked_encode_matches_normal_encode_random, SinkTestHelper, }; use super::*; - use crate::engine::STANDARD; + use crate::engine::general_purpose::STANDARD; #[test] fn basic_display() { diff --git a/src/encode.rs b/src/encode.rs index fbb8379..cb17650 100644 --- a/src/encode.rs +++ b/src/encode.rs @@ -5,7 +5,7 @@ use core::fmt; use std::error; #[cfg(any(feature = "alloc", feature = "std", test))] -use crate::engine::STANDARD; +use crate::engine::general_purpose::STANDARD; use crate::engine::{Config, Engine}; use crate::PAD_BYTE; @@ -161,10 +161,7 @@ mod tests { use crate::{ alphabet, - engine::{ - general_purpose::{GeneralPurpose, NO_PAD}, - STANDARD, - }, + engine::general_purpose::{GeneralPurpose, NO_PAD, STANDARD}, tests::{assert_encode_sanity, random_config, random_engine}, }; use rand::{ diff --git a/src/engine/general_purpose/decode.rs b/src/engine/general_purpose/decode.rs index 3eea4e6..e9fd788 100644 --- a/src/engine/general_purpose/decode.rs +++ b/src/engine/general_purpose/decode.rs @@ -326,7 +326,7 @@ fn write_u64(output: &mut [u8], value: u64) { mod tests { use super::*; - use crate::engine::STANDARD; + use crate::engine::general_purpose::STANDARD; #[test] fn decode_chunk_precise_writes_only_6_bytes() { diff --git a/src/engine/general_purpose/mod.rs b/src/engine/general_purpose/mod.rs index 95bbf46..af8897b 100644 --- a/src/engine/general_purpose/mod.rs +++ b/src/engine/general_purpose/mod.rs @@ -237,7 +237,7 @@ fn read_u64(s: &[u8]) -> u64 { /// /// The constants [PAD] and [NO_PAD] cover most use cases. /// -/// To specify the characters used, see [crate::alphabet::Alphabet]. +/// To specify the characters used, see [Alphabet]. #[derive(Clone, Copy, Debug)] pub struct GeneralPurposeConfig { encode_padding: bool, @@ -325,16 +325,16 @@ impl Config for GeneralPurposeConfig { } } -/// A [GeneralPurpose] engine using the [crate::alphabet::STANDARD] base64 alphabet and [crate::engine::general_purpose::PAD] config. +/// A [GeneralPurpose] engine using the [alphabet::STANDARD] base64 alphabet and [PAD] config. pub const STANDARD: GeneralPurpose = GeneralPurpose::new(&alphabet::STANDARD, PAD); -/// A [GeneralPurpose] engine using the [crate::alphabet::STANDARD] base64 alphabet and [crate::engine::general_purpose::NO_PAD] config. +/// A [GeneralPurpose] engine using the [alphabet::STANDARD] base64 alphabet and [NO_PAD] config. pub const STANDARD_NO_PAD: GeneralPurpose = GeneralPurpose::new(&alphabet::STANDARD, NO_PAD); -/// A [GeneralPurpose] engine using the [crate::alphabet::URL_SAFE] base64 alphabet and [crate::engine::general_purpose::PAD] config. +/// A [GeneralPurpose] engine using the [alphabet::URL_SAFE] base64 alphabet and [PAD] config. pub const URL_SAFE: GeneralPurpose = GeneralPurpose::new(&alphabet::URL_SAFE, PAD); -/// A [GeneralPurpose] engine using the [crate::alphabet::URL_SAFE] base64 alphabet and [crate::engine::general_purpose::NO_PAD] config. +/// A [GeneralPurpose] engine using the [alphabet::URL_SAFE] base64 alphabet and [NO_PAD] config. pub const URL_SAFE_NO_PAD: GeneralPurpose = GeneralPurpose::new(&alphabet::URL_SAFE, NO_PAD); /// Include padding bytes when encoding, and require that they be present when decoding. diff --git a/src/engine/mod.rs b/src/engine/mod.rs index 50c509b..4794b00 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -19,9 +19,7 @@ mod naive; #[cfg(test)] mod tests; -pub use general_purpose::{ - GeneralPurpose, GeneralPurposeConfig, STANDARD, STANDARD_NO_PAD, URL_SAFE, URL_SAFE_NO_PAD, -}; +pub use general_purpose::{GeneralPurpose, GeneralPurposeConfig}; /// An `Engine` provides low-level encoding and decoding operations that all other higher-level parts of the API use. Users of the library will generally not need to implement this. /// @@ -29,7 +27,7 @@ pub use general_purpose::{ /// [GeneralPurpose] that offers good speed and works on any CPU, with more choices /// coming later, like a constant-time one when side channel resistance is called for, and vendor-specific vectorized ones for more speed. /// -/// See [STANDARD] if you just want standard base64. Otherwise, when possible, it's +/// See [general_purpose::STANDARD_NO_PAD] if you just want standard base64. Otherwise, when possible, it's /// recommended to store the engine in a `const` so that references to it won't pose any lifetime /// issues, and to avoid repeating the cost of engine setup. /// @@ -112,16 +110,15 @@ pub trait Engine: Send + Sync { /// # Example /// /// ```rust - /// use base64::Engine as _; - /// const URL_SAFE_ENGINE: base64::engine::GeneralPurpose = - /// base64::engine::GeneralPurpose::new( - /// &base64::alphabet::URL_SAFE, - /// base64::engine::general_purpose::NO_PAD); + /// use base64::{Engine as _, engine::{self, general_purpose}, alphabet}; /// - /// let b64 = base64::engine::STANDARD.encode(b"hello world~"); + /// let b64 = general_purpose::STANDARD.encode(b"hello world~"); /// println!("{}", b64); /// - /// let b64_url = URL_SAFE_ENGINE.encode(b"hello internet~"); + /// const CUSTOM_ENGINE: engine::GeneralPurpose = + /// engine::GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::NO_PAD); + /// + /// let b64_url = CUSTOM_ENGINE.encode(b"hello internet~"); #[cfg(any(feature = "alloc", feature = "std", test))] fn encode>(&self, input: T) -> String { let encoded_size = encoded_len(input.as_ref().len(), self.config().encode_padding()) @@ -139,18 +136,17 @@ pub trait Engine: Send + Sync { /// # Example /// /// ```rust - /// use base64::Engine as _; - /// const URL_SAFE_ENGINE: base64::engine::GeneralPurpose = - /// base64::engine::GeneralPurpose::new( - /// &base64::alphabet::URL_SAFE, - /// base64::engine::general_purpose::NO_PAD); + /// use base64::{Engine as _, engine::{self, general_purpose}, alphabet}; + /// const CUSTOM_ENGINE: engine::GeneralPurpose = + /// engine::GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::NO_PAD); + /// /// fn main() { /// let mut buf = String::new(); - /// base64::engine::STANDARD.encode_string(b"hello world~", &mut buf); + /// general_purpose::STANDARD.encode_string(b"hello world~", &mut buf); /// println!("{}", buf); /// /// buf.clear(); - /// URL_SAFE_ENGINE.encode_string(b"hello internet~", &mut buf); + /// CUSTOM_ENGINE.encode_string(b"hello internet~", &mut buf); /// println!("{}", buf); /// } /// ``` @@ -176,18 +172,18 @@ pub trait Engine: Send + Sync { /// # Example /// /// ```rust - /// use base64::{engine, Engine as _}; + /// use base64::{Engine as _, engine::general_purpose}; /// let s = b"hello internet!"; /// let mut buf = Vec::new(); /// // make sure we'll have a slice big enough for base64 + padding /// buf.resize(s.len() * 4 / 3 + 4, 0); /// - /// let bytes_written = engine::STANDARD.encode_slice(s, &mut buf).unwrap(); + /// let bytes_written = general_purpose::STANDARD.encode_slice(s, &mut buf).unwrap(); /// /// // shorten our vec down to just what was written /// buf.truncate(bytes_written); /// - /// assert_eq!(s, engine::STANDARD.decode(&buf).unwrap().as_slice()); + /// assert_eq!(s, general_purpose::STANDARD.decode(&buf).unwrap().as_slice()); /// ``` fn encode_slice>( &self, @@ -216,17 +212,18 @@ pub trait Engine: Send + Sync { /// # Example /// /// ```rust - /// use base64::{Engine as _, Engine}; - /// - /// let bytes = base64::engine::STANDARD.decode("aGVsbG8gd29ybGR+Cg==").unwrap(); - /// println!("{:?}", bytes); - /// - /// // custom engine setup - /// let bytes_url = base64::engine::GeneralPurpose::new( - /// &base64::alphabet::URL_SAFE, - /// base64::engine::general_purpose::NO_PAD) - /// .decode("aGVsbG8gaW50ZXJuZXR-Cg").unwrap(); - /// println!("{:?}", bytes_url); + /// use base64::{Engine as _, alphabet, engine::{self, general_purpose}}; + /// + /// let bytes = general_purpose::STANDARD + /// .decode("aGVsbG8gd29ybGR+Cg==").unwrap(); + /// println!("{:?}", bytes); + /// + /// // custom engine setup + /// let bytes_url = engine::GeneralPurpose::new( + /// &alphabet::URL_SAFE, + /// general_purpose::NO_PAD) + /// .decode("aGVsbG8gaW50ZXJuZXR-Cg").unwrap(); + /// println!("{:?}", bytes_url); /// ``` /// /// # Panics @@ -253,25 +250,22 @@ pub trait Engine: Send + Sync { /// # Example /// /// ```rust - /// const URL_SAFE_ENGINE: base64::engine::GeneralPurpose = - /// base64::engine::GeneralPurpose::new( - /// &base64::alphabet::URL_SAFE, - /// base64::engine::general_purpose::PAD); + /// use base64::{Engine as _, alphabet, engine::{self, general_purpose}}; + /// const CUSTOM_ENGINE: engine::GeneralPurpose = + /// engine::GeneralPurpose::new(&alphabet::URL_SAFE, general_purpose::PAD); /// /// fn main() { /// use base64::Engine; /// let mut buffer = Vec::::new(); /// // with the default engine - /// base64::engine::STANDARD.decode_vec( - /// "aGVsbG8gd29ybGR+Cg==", - /// &mut buffer, - /// ).unwrap(); + /// general_purpose::STANDARD + /// .decode_vec("aGVsbG8gd29ybGR+Cg==", &mut buffer,).unwrap(); /// println!("{:?}", buffer); /// /// buffer.clear(); /// /// // with a custom engine - /// URL_SAFE_ENGINE.decode_vec( + /// CUSTOM_ENGINE.decode_vec( /// "aGVsbG8gaW50ZXJuZXR-Cg==", /// &mut buffer, /// ).unwrap(); diff --git a/src/lib.rs b/src/lib.rs index 0a3ec6a..deff840 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,14 +1,11 @@ //! # Getting started //! -//! tl;dr: -//! -//! 1. Perhaps one of the already available consts will suit: -//! - [engine::STANDARD] -//! - [engine::STANDARD_NO_PAD] -//! - [engine::URL_SAFE] -//! - [engine::URL_SAFE_NO_PAD] +//! 1. Perhaps one of the preconfigured engines in [engine::general_purpose] will suit, e.g. +//! [engine::general_purpose::STANDARD_NO_PAD]. +//! - These are re-exported in [prelude] with a `BASE64_` prefix for those who prefer to +//! `use ...::prelude::*` or equivalent, e.g. [prelude::BASE64_STANDARD_NO_PAD] //! 1. If not, choose which alphabet you want. Most usage will want [alphabet::STANDARD] or [alphabet::URL_SAFE]. -//! 1. Choose which [Engine] you want. For the moment there is only one: [engine::GeneralPurpose]. +//! 1. Choose which [Engine] implementation you want. For the moment there is only one: [engine::GeneralPurpose]. //! 1. Configure the engine appropriately using the engine's `Config` type. //! - This is where you'll select whether to add padding (when encoding) or expect it (when //! decoding). If given the choice, prefer no padding. @@ -28,7 +25,7 @@ //! Once you have an `Alphabet`, you can pick which `Engine` you want. A few parts of the public //! API provide a default, but otherwise the user must provide an `Engine` to use. //! -//! See [engine::Engine] for more. +//! See [Engine] for more. //! //! ## Config //! @@ -85,15 +82,15 @@ //! ## Using predefined engines //! //! ``` -//! use base64::{engine, Engine as _}; +//! use base64::{Engine as _, engine::general_purpose}; //! //! let orig = b"data"; -//! let encoded: String = engine::STANDARD_NO_PAD.encode(orig); +//! let encoded: String = general_purpose::STANDARD_NO_PAD.encode(orig); //! assert_eq!("ZGF0YQ", encoded); -//! assert_eq!(orig.as_slice(), &engine::STANDARD_NO_PAD.decode(encoded).unwrap()); +//! assert_eq!(orig.as_slice(), &general_purpose::STANDARD_NO_PAD.decode(encoded).unwrap()); //! //! // or, URL-safe -//! let encoded_url = engine::URL_SAFE_NO_PAD.encode(orig); +//! let encoded_url = general_purpose::URL_SAFE_NO_PAD.encode(orig); //! ``` //! //! ## Custom alphabet, config, and engine @@ -107,14 +104,14 @@ //! .unwrap(); //! //! // a very weird config that encodes with padding but requires no padding when decoding...? -//! let config = engine::GeneralPurposeConfig::new() +//! let crazy_config = engine::GeneralPurposeConfig::new() //! .with_decode_allow_trailing_bits(true) //! .with_encode_padding(true) //! .with_decode_padding_mode(engine::DecodePaddingMode::RequireNone); //! -//! let engine = engine::GeneralPurpose::new(&alphabet, config); +//! let crazy_engine = engine::GeneralPurpose::new(&alphabet, crazy_config); //! -//! let encoded = engine.encode(b"abc 123"); +//! let encoded = crazy_engine.encode(b"abc 123"); //! //! ``` //! @@ -174,6 +171,8 @@ pub use crate::decode::{decode, decode_engine, decode_engine_vec}; #[allow(deprecated)] pub use crate::decode::{decode_engine_slice, decoded_len_estimate, DecodeError, DecodeSliceError}; +pub mod prelude; + #[cfg(test)] mod tests; diff --git a/src/prelude.rs b/src/prelude.rs new file mode 100644 index 0000000..a88785e --- /dev/null +++ b/src/prelude.rs @@ -0,0 +1,16 @@ +//! Preconfigured engines for common use cases. +//! +//! These are re-exports of `const` engines in [crate::engine::general_purpose], renamed with a `BASE64_` +//! prefix for those who prefer to `use` the entire path to a name. +//! +//! # Examples +//! +//! ``` +//! use base64::{Engine as _, prelude::BASE64_STANDARD_NO_PAD}; +//! +//! assert_eq!("c29tZSBieXRlcw", &BASE64_STANDARD_NO_PAD.encode(b"some bytes")); +//! ``` +pub use crate::engine::general_purpose::STANDARD as BASE64_STANDARD; +pub use crate::engine::general_purpose::STANDARD_NO_PAD as BASE64_STANDARD_NO_PAD; +pub use crate::engine::general_purpose::URL_SAFE as BASE64_URL_SAFE; +pub use crate::engine::general_purpose::URL_SAFE_NO_PAD as BASE64_URL_SAFE_NO_PAD; diff --git a/src/read/decoder.rs b/src/read/decoder.rs index 61650b1..4888c9c 100644 --- a/src/read/decoder.rs +++ b/src/read/decoder.rs @@ -15,12 +15,13 @@ const DECODED_CHUNK_SIZE: usize = 3; /// ``` /// use std::io::Read; /// use std::io::Cursor; +/// use base64::engine::general_purpose; /// /// // use a cursor as the simplest possible `Read` -- in real code this is probably a file, etc. /// let mut wrapped_reader = Cursor::new(b"YXNkZg=="); /// let mut decoder = base64::read::DecoderReader::new( /// &mut wrapped_reader, -/// &base64::engine::STANDARD); +/// &general_purpose::STANDARD); /// /// // handle errors as you normally would /// let mut result = Vec::new(); diff --git a/src/read/decoder_tests.rs b/src/read/decoder_tests.rs index df89687..65d58d8 100644 --- a/src/read/decoder_tests.rs +++ b/src/read/decoder_tests.rs @@ -8,7 +8,7 @@ use rand::{Rng as _, RngCore as _}; use super::decoder::{DecoderReader, BUF_SIZE}; use crate::{ - engine::{Engine, GeneralPurpose, STANDARD}, + engine::{general_purpose::STANDARD, Engine, GeneralPurpose}, tests::{random_alphabet, random_config, random_engine}, DecodeError, }; diff --git a/src/write/encoder.rs b/src/write/encoder.rs index 1e024ed..1c19bb4 100644 --- a/src/write/encoder.rs +++ b/src/write/encoder.rs @@ -22,11 +22,10 @@ const MIN_ENCODE_CHUNK_SIZE: usize = 3; /// /// ``` /// use std::io::Write; +/// use base64::engine::general_purpose; /// /// // use a vec as the simplest possible `Write` -- in real code this is probably a file, etc. -/// let mut enc = base64::write::EncoderWriter::new( -/// Vec::new(), -/// &base64::engine::STANDARD); +/// let mut enc = base64::write::EncoderWriter::new(Vec::new(), &general_purpose::STANDARD); /// /// // handle errors as you normally would /// enc.write_all(b"asdf").unwrap(); diff --git a/src/write/encoder_string_writer.rs b/src/write/encoder_string_writer.rs index 89520e6..9394dc9 100644 --- a/src/write/encoder_string_writer.rs +++ b/src/write/encoder_string_writer.rs @@ -12,9 +12,9 @@ use std::io; /// /// ``` /// use std::io::Write; +/// use base64::engine::general_purpose; /// -/// let mut enc = base64::write::EncoderStringWriter::new( -/// &base64::engine::STANDARD); +/// let mut enc = base64::write::EncoderStringWriter::new(&general_purpose::STANDARD); /// /// enc.write_all(b"asdf").unwrap(); /// @@ -28,12 +28,13 @@ use std::io; /// /// ``` /// use std::io::Write; +/// use base64::engine::general_purpose; /// /// let mut buf = String::from("base64: "); /// /// let mut enc = base64::write::EncoderStringWriter::from_consumer( /// &mut buf, -/// &base64::engine::STANDARD); +/// &general_purpose::STANDARD); /// /// enc.write_all(b"asdf").unwrap(); /// diff --git a/src/write/mod.rs b/src/write/mod.rs index ef9be61..2a617db 100644 --- a/src/write/mod.rs +++ b/src/write/mod.rs @@ -1,9 +1,11 @@ //! Implementations of `io::Write` to transparently handle base64. mod encoder; mod encoder_string_writer; -pub use self::encoder::EncoderWriter; -pub use self::encoder_string_writer::EncoderStringWriter; -pub use self::encoder_string_writer::StrConsumer; + +pub use self::{ + encoder::EncoderWriter, + encoder_string_writer::{EncoderStringWriter, StrConsumer}, +}; #[cfg(test)] mod encoder_tests; diff --git a/tests/encode.rs b/tests/encode.rs index cecd591..2e1f893 100644 --- a/tests/encode.rs +++ b/tests/encode.rs @@ -1,4 +1,6 @@ -use base64::{alphabet::URL_SAFE, engine::general_purpose::PAD, engine::STANDARD, *}; +use base64::{ + alphabet::URL_SAFE, engine::general_purpose::PAD, engine::general_purpose::STANDARD, *, +}; fn compare_encode(expected: &str, target: &[u8]) { assert_eq!(expected, STANDARD.encode(target)); diff --git a/tests/tests.rs b/tests/tests.rs index cd170f2..eceff40 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1,6 +1,6 @@ use rand::{Rng, SeedableRng}; -use base64::engine::{Engine, STANDARD}; +use base64::engine::{general_purpose::STANDARD, Engine}; use base64::*; use base64::engine::general_purpose::{GeneralPurpose, NO_PAD};