//// Encode base64 strings according to RFC 2045. //// //// See the following link for reference: //// - 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() }