Trait base64::engine::Engine

source ·
pub trait Engine: Send + Sync {
    type Config: Config;
    type DecodeEstimate: DecodeEstimate;

    fn config(&self) -> &Self::Config;

    fn encode<T: AsRef<[u8]>>(&self, input: T) -> String { ... }
    fn encode_string<T: AsRef<[u8]>>(&self, input: T, output_buf: &mut String) { ... }
    fn encode_slice<T: AsRef<[u8]>>(
        &self,
        input: T,
        output_buf: &mut [u8]
    ) -> Result<usize, EncodeSliceError> { ... } fn decode<T: AsRef<[u8]>>(&self, input: T) -> Result<Vec<u8>, DecodeError> { ... } fn decode_vec<T: AsRef<[u8]>>(
        &self,
        input: T,
        buffer: &mut Vec<u8>
    ) -> Result<(), DecodeError> { ... } fn decode_slice<T: AsRef<[u8]>>(
        &self,
        input: T,
        output: &mut [u8]
    ) -> Result<usize, DecodeSliceError> { ... } }
Expand description

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.

Different implementations offer different characteristics. The library currently ships with 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 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.

Since almost nobody will need to implement Engine, docs for internal methods are hidden.

Required Associated Types§

The config type used by this engine

The decode estimate used by this engine

Required Methods§

Returns the config for this engine.

Provided Methods§

Encode arbitrary octets as base64 using the provided Engine. Returns a String.

Example
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);

let b64 = base64::engine::STANDARD.encode(b"hello world~");
println!("{}", b64);

let b64_url = URL_SAFE_ENGINE.encode(b"hello internet~");
Examples found in repository?
src/encode.rs (line 19)
18
19
20
21
22
23
24
25
26
27
28
29
30
pub fn encode<T: AsRef<[u8]>>(input: T) -> String {
    STANDARD.encode(input)
}

///Encode arbitrary octets as base64 using the provided `Engine` into a new `String`.
///
/// See [Engine::encode].
#[allow(unused)]
#[deprecated(since = "0.21.0", note = "Use Engine::encode")]
#[cfg(any(feature = "alloc", feature = "std", test))]
pub fn encode_engine<E: Engine, T: AsRef<[u8]>>(input: T, engine: &E) -> String {
    engine.encode(input)
}

Encode arbitrary octets as base64 into a supplied String. Writes into the supplied String, which may allocate if its internal buffer isn’t big enough.

Example
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);
fn main() {
    let mut buf = String::new();
    base64::engine::STANDARD.encode_string(b"hello world~", &mut buf);
    println!("{}", buf);

    buf.clear();
    URL_SAFE_ENGINE.encode_string(b"hello internet~", &mut buf);
    println!("{}", buf);
}
Examples found in repository?
src/encode.rs (line 43)
38
39
40
41
42
43
44
pub fn encode_engine_string<E: Engine, T: AsRef<[u8]>>(
    input: T,
    output_buf: &mut String,
    engine: &E,
) {
    engine.encode_string(input, output_buf)
}

Encode arbitrary octets as base64 into a supplied slice. Writes into the supplied output buffer.

This is useful if you wish to avoid allocation entirely (e.g. encoding into a stack-resident or statically-allocated buffer).

Example
use base64::{engine, Engine as _};
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();

// shorten our vec down to just what was written
buf.truncate(bytes_written);

assert_eq!(s, engine::STANDARD.decode(&buf).unwrap().as_slice());
Examples found in repository?
src/encode.rs (line 56)
51
52
53
54
55
56
57
pub fn encode_engine_slice<E: Engine, T: AsRef<[u8]>>(
    input: T,
    output_buf: &mut [u8],
    engine: &E,
) -> Result<usize, EncodeSliceError> {
    engine.encode_slice(input, output_buf)
}
More examples
Hide additional examples
src/write/encoder.rs (lines 154-157)
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
    fn write_final_leftovers(&mut self) -> Result<()> {
        if self.delegate.is_none() {
            // finish() has already successfully called this, and we are now in drop() with a None
            // writer, so just no-op
            return Ok(());
        }

        self.write_all_encoded_output()?;

        if self.extra_input_occupied_len > 0 {
            let encoded_len = self
                .engine
                .encode_slice(
                    &self.extra_input[..self.extra_input_occupied_len],
                    &mut self.output[..],
                )
                .expect("buffer is large enough");

            self.output_occupied_len = encoded_len;

            self.write_all_encoded_output()?;

            // write succeeded, do not write the encoding of extra again if finish() is retried
            self.extra_input_occupied_len = 0;
        }

        Ok(())
    }

Decode from string reference as octets using the specified Engine. Returns a Result containing a Vec<u8>.

Example
    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);
Panics

Panics if decoded length estimation overflows. This would happen for sizes within a few bytes of the maximum value of usize.

Examples found in repository?
src/decode.rs (line 92)
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
pub fn decode<T: AsRef<[u8]>>(input: T) -> Result<Vec<u8>, DecodeError> {
    STANDARD.decode(input)
}

/// Decode from string reference as octets using the specified [Engine].
///
/// See [Engine::decode].
///Returns a `Result` containing a `Vec<u8>`.
#[deprecated(since = "0.21.0", note = "Use Engine::decode")]
#[cfg(any(feature = "alloc", feature = "std", test))]
pub fn decode_engine<E: Engine, T: AsRef<[u8]>>(
    input: T,
    engine: &E,
) -> Result<Vec<u8>, DecodeError> {
    engine.decode(input)
}

Decode from string reference as octets. Writes into the supplied Vec, which may allocate if its internal buffer isn’t big enough. Returns a Result containing an empty tuple, aka ().

Example
const URL_SAFE_ENGINE: base64::engine::GeneralPurpose =
    base64::engine::GeneralPurpose::new(
        &base64::alphabet::URL_SAFE,
        base64::engine::general_purpose::PAD);

fn main() {
    use base64::Engine;
    let mut buffer = Vec::<u8>::new();
    // with the default engine
    base64::engine::STANDARD.decode_vec(
        "aGVsbG8gd29ybGR+Cg==",
        &mut buffer,
    ).unwrap();
    println!("{:?}", buffer);

    buffer.clear();

    // with a custom engine
    URL_SAFE_ENGINE.decode_vec(
        "aGVsbG8gaW50ZXJuZXR-Cg==",
        &mut buffer,
    ).unwrap();
    println!("{:?}", buffer);
}
Panics

Panics if decoded length estimation overflows. This would happen for sizes within a few bytes of the maximum value of usize.

Examples found in repository?
src/decode.rs (line 118)
113
114
115
116
117
118
119
pub fn decode_engine_vec<E: Engine, T: AsRef<[u8]>>(
    input: T,
    buffer: &mut Vec<u8>,
    engine: &E,
) -> Result<(), DecodeError> {
    engine.decode_vec(input, buffer)
}

Decode the input into the provided output slice.

This will not write any bytes past exactly what is decoded (no stray garbage bytes at the end).

See crate::decoded_len_estimate for calculating buffer sizes.

Panics

Panics if decoded length estimation overflows. This would happen for sizes within a few bytes of the maximum value of usize.

Examples found in repository?
src/decode.rs (line 130)
125
126
127
128
129
130
131
pub fn decode_engine_slice<E: Engine, T: AsRef<[u8]>>(
    input: T,
    output: &mut [u8],
    engine: &E,
) -> Result<usize, DecodeSliceError> {
    engine.decode_slice(input, output)
}

Implementors§