// Copyright 2026 Leo Cheng
// SPDX-License-Identifier: Apache-2.0
///|
/// The four examples RFC 2397 ยง4 prints, then the same payload written both
/// ways, then the two things `strict` refuses.
fn main raise {
for
text in [
"data:,A%20brief%20note", "data:text/plain;charset=iso-8859-7,%be%fg%be", "data:image/gif;base64,AAEC",
"data:application/vnd-xxx-query,select_vcount,fcol_from_fieldtable/local",
] {
let url = @dataurl.Url::decode(text[:])
println(text)
println(" type " + url.kind)
println(" charset " + url.charset())
println(" octets " + octets(url.data))
println("")
}
// One payload, both spellings. Base64 by default, because it is the only one
// that does not grow for octets that are not text.
let icon = @dataurl.Url::new(b"\x89PNG\r\n\x1a\n", kind="image/png")
println("base64 " + icon.encode())
println("percent " + icon.encode(base64=false))
println("")
// A media type equal to the default is left out, and reading puts it back.
let note = @dataurl.Url::new(@utf8.encode("A brief note"))
println("written " + note.encode(base64=false))
println(
"read back " + @dataurl.Url::decode(note.encode(base64=false)[:]).kind,
)
println("")
// What a browser lets pass, and what `strict` will not.
for text in ["data:,100%", "data:;base64,AA\nEC"] {
let lenient = @dataurl.Url::decode(text[:])
println("lenient " + octets(lenient.data))
try @dataurl.Url::decode(text[:], strict=true) |> ignore catch {
e => println("strict refused: " + e.to_repr().to_string())
}
}
}
///|
fn octets(data : Bytes) -> String {
let out = StringBuilder()
for i = 0; i < data.length(); i = i + 1 {
let b = data[i].to_int()
if b >= 0x20 && b < 0x7F {
out.write_char(b.unsafe_to_char())
} else {
out.write_string("<\{b}>")
}
}
out.to_string()
}