//// Encode base64 strings according to RFC 2045.
////
//// See the following link for reference:
//// - <https://tools.ietf.org/html/rfc2045>
import gleam/bit_array
import gleam/list
import gleam/pair
import gleam/string
import internal/encoder/encoding
/// Estimates the base64 encoded size of a string in bytes.
pub fn estimate_encoded_size(
of string: String,
) -> Result(Int, encoding.EncoderError) {
Ok(string.byte_size(string) * 8 / 6)
}
/// Base64 encode a string, taking the preferred line size into
/// account and pretending to start the first line at the passed
/// start position.
pub fn encode_string(
encode string: String,
start position: Int,
preferred_size preferred_size: Int,
) -> Result(List(String), encoding.EncoderError) {
let chunk_size = preferred_size * 6 / 8
string
|> string.split("")
|> chunk(position, chunk_size)
|> list.map(bit_array.from_string)
|> list.map(bit_array.base64_encode(_, True))
|> Ok
}
fn chunk(
characters: List(String),
used_size: Int,
chunk_size: Int,
) -> List(String) {
characters
|> list.fold(#(used_size, []), fn(accumulator, character) {
let #(used_size, chunks) = accumulator
let character_size = string.byte_size(character)
case chunks {
[] -> #(character_size, [character])
[chunk, ..other_chunks] if used_size + character_size <= chunk_size -> #(
used_size + character_size,
[chunk <> character, ..other_chunks],
)
chunks -> #(character_size, [character, ..chunks])
}
})
|> pair.second()
|> list.reverse()
}