Encoding
Base64, base64url, hex and percent-encoding read back, files as base64 and back, and query strings as maps.
Version 1.0.0 · 10 functions · 3 crates
Functions
What use encoding.qwer gives a program, with the types Quillo sees. To take only some, or under other names: use base64_encode, base64_decode from encoding (Quillo 0.6).
base64_encode(text: str) → strtext as base64, with padding.
base64_decode(b64: str) → stror an errorBase64 back to text; padding is optional, and spaces and line breaks are ignored.
base64url_encode(text: str) → strtext as base64url without padding, as JWTs and URLs carry it.
base64url_decode(b64: str) → stror an errorBase64url back to text, with or without padding.
file_to_base64(path: str) → stror an errorA file's bytes as base64: an image for a data: URL, an attachment for an API.
base64_to_file(b64: str, path: str) → intor an errorBase64 written to a file as the bytes it holds; how many bytes were written.
hex_encode(text: str) → strtext as lower-case hex.
hex_decode(h: str) → stror an errorHex back to text.
url_decode(text: str) → stror an errorPercent-encoding undone: caf%C3%A9 is café. A + stays a +.
form_decode(text: str) → mapor an errorA query string or form body as a map: a=1&b=x+y is { a: "1", b: "x y" }. A key given twice keeps the last.
Get it
$ quillo install encoding # encoding.qwer into this folder$ quillo install encoding --example # and its example, encoding.qweOr with curl:
$ curl -O https://quillolang.org/plugins/files/encoding.qwer$ curl -O https://quillolang.org/plugins/files/encoding.qweThen, in your program, all of it or only what you call:
use encoding.qweruse base64_encode, base64_decode from encoding // Quillo 0.6: only theseIt uses these crates, which cargo fetches the first time the plugin is built:
base64 = "0.22"hex = "0.4"percent-encoding = "2"Example
// Base64, hex and query strings, read back.//// quillo run encoding.qwe then open http://localhost:8080/decode?b64=Y2Fmw6kuse "encoding.qwer"route GET /decode ? { b64: str } = { text: base64_decode(b64)?, again: base64_encode(base64_decode(b64)?) }route GET /hex ? { text: str } = { hex: hex_encode(text), back: hex_decode(hex_encode(text))? }route GET /form = form_decode("name=Ada+Lovelace&city=London%2C%20UK")?$ quillo run encoding.qwe$ curl 'localhost:8080/decode?b64=Y2Fmw6k'$ curl 'localhost:8080/hex?text=hi'$ curl 'localhost:8080/form'Source
//! Base64, base64url, hex and percent-encoding, both ways: Quillo makes them, this reads them back.//! version: 1.0.0//!//! [dependencies]//! base64 = "0.22"//! hex = "0.4"//! percent-encoding = "2"use base64::engine::general_purpose::{STANDARD, STANDARD_NO_PAD, URL_SAFE_NO_PAD};use base64::Engine;use std::collections::HashMap;fn utf8(bytes: Vec<u8>) -> Result<String, String> { String::from_utf8(bytes).map_err(|_| "the bytes are not UTF-8 text: use base64_to_file for binary data".to_string())}/// `text` as base64, with padding.pub fn base64_encode(text: &str) -> String { STANDARD.encode(text)}/// Base64 back to text; padding is optional, and spaces and line breaks are ignored.pub fn base64_decode(b64: &str) -> Result<String, String> { let clean: String = b64.chars().filter(|c| !c.is_whitespace()).collect(); utf8(STANDARD_NO_PAD.decode(clean.trim_end_matches('=')).map_err(|e| e.to_string())?)}/// `text` as base64url without padding, as JWTs and URLs carry it.pub fn base64url_encode(text: &str) -> String { URL_SAFE_NO_PAD.encode(text)}/// Base64url back to text, with or without padding.pub fn base64url_decode(b64: &str) -> Result<String, String> { utf8(URL_SAFE_NO_PAD.decode(b64.trim().trim_end_matches('=')).map_err(|e| e.to_string())?)}/// A file's bytes as base64: an image for a `data:` URL, an attachment for an API.pub fn file_to_base64(path: &str) -> Result<String, String> { Ok(STANDARD.encode(std::fs::read(path).map_err(|e| format!("{}: {}", path, e))?))}/// Base64 written to a file as the bytes it holds; how many bytes were written.pub fn base64_to_file(b64: &str, path: &str) -> Result<i64, String> { let clean: String = b64.chars().filter(|c| !c.is_whitespace()).collect(); let bytes = STANDARD_NO_PAD.decode(clean.trim_end_matches('=')).map_err(|e| e.to_string())?; std::fs::write(path, &bytes).map_err(|e| format!("{}: {}", path, e))?; Ok(bytes.len() as i64)}/// `text` as lower-case hex.pub fn hex_encode(text: &str) -> String { hex::encode(text)}/// Hex back to text.pub fn hex_decode(h: &str) -> Result<String, String> { utf8(hex::decode(h.trim()).map_err(|e| e.to_string())?)}/// Percent-encoding undone: `caf%C3%A9` is `café`. A `+` stays a `+`.pub fn url_decode(text: &str) -> Result<String, String> { percent_encoding::percent_decode_str(text).decode_utf8().map(|s| s.into_owned()).map_err(|e| e.to_string())}/// A query string or form body as a map: `a=1&b=x+y` is `{ a: "1", b: "x y" }`. A key given twice keeps the last.pub fn form_decode(text: &str) -> Result<HashMap<String, String>, String> { let mut out = HashMap::new(); for pair in text.trim_start_matches('?').split('&').filter(|p| !p.is_empty()) { let (k, v) = pair.split_once('=').unwrap_or((pair, "")); out.insert(url_decode(&k.replace('+', " "))?, url_decode(&v.replace('+', " "))?); } Ok(out)}Related
bencode.qwer · 1.0.0Bencode, BitTorrent's format, encoded and decoded; .torrent files read (files, sizes, trackers, info hash, magnet link) and made from a file.7 views · 10 downloadsFixed width fixed_width.qwer · 1.0.0Fixed-width records read and written from a column spec: bank payment files, payroll exports and mainframe formats.8 views · 8 downloadsGzip gzip.qwer · 1.0.0Gzip files and text, and unpack them: smaller backups, exports and payloads.7 views · 6 downloadsJSON Schema json_schema.qwer · 1.0.0Check values against a JSON Schema (drafts 4 to 2020-12), with every error and the path of the value at fault.8 views · 8 downloadsLDIF ldif.qwer · 1.0.0LDIF by RFC 2849 read and written: folded lines, comments that fold too, base64 and `:<` values, attribute options, controls, and add, delete, modify and modrdn records. Values base64-encoded exactly where the RFC says, DNs taken apart by RFC 4514 with escapes, and the change records that turn one export into another.1 view · 6 downloadsParquet parquet.qwer · 1.0.0Parquet files for data lakes, DuckDB, Spark and pandas: rows written with their column types found, and read back as rows.6 views · 9 downloadsThread 0 posts
On Encoding: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.