Encoding and decoding text plantuml diagrams to facilitate communication of them through URL.
Consider the next plain text plantuml diagram:
@startuml
PUML -> RUST: HELLO
@enduml
It can be encoded to 0IO0sVz0StHXSdHrRMmAK5LDJ20jFY1ILLDKEY18HKnCJo0AG6LkP7LjR000
and with the help of the plantuml server (https://www.plantuml.com/plantuml/uml/
) it can be shared through URL.
Also, it can be decoded in the opposite direction.
Plantuml declares support for the following compression algorithms:
But in fact, plantuml supports only deflate
(with additional transformations close to base64) and hex
(with additional prefix ~h
). brotli
is turned off. So the crate supports only deflate
and hex
too.
In order to use this crate, you have to add it under [dependencies]
to your Cargo.toml
:
[dependencies]
plantuml_encoding = "2.0.3"
There is an article very close describing the library under the hood.
use plantuml_encoding::{
decode_plantuml_deflate, decode_plantuml_hex,
encode_plantuml_deflate, encode_plantuml_hex,
FromPlantumlError,
};
fn main() -> Result<(), FromPlantumlError> {
// original puml
println!("--- Original puml ---");
let puml = "@startuml\nPUML -> RUST\n@enduml";
println!("Original puml:\n{}\n", puml);
// deflate
println!("--- Deflate ---");
let encoded_deflate = encode_plantuml_deflate(puml)?;
let decoded_deflate = decode_plantuml_deflate(&encoded_deflate)?;
println!("Encoded deflate: {}", encoded_deflate);
println!("Decoded deflate:\n{}\n", decoded_deflate);
// hex
println!("--- Hex ---");
let encoded_hex = encode_plantuml_hex(puml)?;
let decoded_hex = decode_plantuml_hex(&encoded_hex)?;
println!("Encoded hex: {}", encoded_hex);
println!("Decoded hex:\n{}\n", decoded_hex);
// deflate errors
println!("--- Deflate errors ---");
let empty_encoded_deflate = "";
let decoded_deflate = decode_plantuml_deflate(empty_encoded_deflate)
.unwrap_or_else(|_| "It's not decoded deflate".to_string());
println!("Decoded deflate error:\n{}\n", decoded_deflate);
let decoded_deflate = match decode_plantuml_deflate(empty_encoded_deflate) {
Ok(plantuml) => plantuml,
Err(FromPlantumlError(err)) => {
eprintln!("Decoded deflate error: {:?}", err);
String::from("Result from deflate error")
}
};
println!("Match decoded deflate error result:\n{}\n", decoded_deflate);
// hex errors
println!("--- Hex errors ---");
let decoded_hex = match decode_plantuml_hex("12345") {
Ok(plantuml) => plantuml,
Err(FromPlantumlError(err)) => {
eprintln!("Decoded hex error: {:?}", err);
String::from("Result from hex error")
}
};
println!("Match decoded hex error result:\n{}", decoded_hex);
Ok(())
}
And console output after cargo run
for these examples:
--- Original puml ---
Original puml:
@startuml
PUML -> RUST
@enduml
--- Deflate ---
Encoded deflate: SoWkIImgAStDuGe8zVLHqBLJ20eD3k5oICrB0Ge20000
Decoded deflate:
@startuml
PUML -> RUST
@enduml
--- Hex ---
Encoded hex: ~h407374617274756d6c0a50554d4c202d3e20525553540a40656e64756d6c
Decoded hex:
@startuml
PUML -> RUST
@enduml
--- Deflate errors ---
Decoded deflate error:
It's not decoded deflate
Decoded deflate error: "there is a problem during deflate decoding: `deflate decompression error`"
Match decoded deflate error result:
Result from deflate error
--- Hex errors ---
Decoded hex error: "there is a problem during hex decoding: `Odd number of digits`"
Match decoded hex error result:
Result from hex error
Also, you can consider tests inside the files.