aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.rs89
1 files changed, 87 insertions, 2 deletions
diff --git a/src/main.rs b/src/main.rs
index e7a11a9..235023a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,3 +1,88 @@
-fn main() {
- println!("Hello, world!");
+#[macro_use]
+extern crate rocket;
+
+use quick_xml::events::BytesText;
+use quick_xml::Writer;
+use rocket::http::{ContentType, Status};
+use std::io;
+use std::io::{Cursor, Write};
+use std::process::{Command, Stdio};
+
+fn to_input_svg(text: &str) -> anyhow::Result<Vec<u8>> {
+ let mut writer = Writer::new(Cursor::new(vec![]));
+ writer
+ .create_element("svg")
+ .with_attribute(("xmlns", "http://www.w3.org/2000/svg"))
+ .write_inner_content(|writer| {
+ writer
+ .create_element("style")
+ .write_text_content(BytesText::new("text { font-family: 'linja pona'; }"))?;
+ writer
+ .create_element("text")
+ .write_text_content(BytesText::new(text))?;
+ Ok(())
+ })?;
+ Ok(writer.into_inner().into_inner())
+}
+
+fn to_final_svg(text: &str) -> anyhow::Result<String> {
+ let input_svg = to_input_svg(text)?;
+ let mut inkscape_command = Command::new("inkscape")
+ .args([
+ "--pipe",
+ "--export-type=svg",
+ "--export-area-drawing",
+ "--export-plain-svg",
+ "--export-text-to-path",
+ ])
+ .stdin(Stdio::piped())
+ .stdout(Stdio::piped())
+ .spawn()?;
+
+ inkscape_command
+ .stdin
+ .take()
+ .unwrap()
+ .write_all(&input_svg)?;
+
+ let mut svgo_command = Command::new("svgo")
+ .args(["--config", "./svgo.config.js", "-"])
+ .stdin(Stdio::piped())
+ .stdout(Stdio::piped())
+ .spawn()?;
+
+ io::copy(
+ &mut inkscape_command.stdout.take().unwrap(),
+ &mut svgo_command.stdin.take().unwrap(),
+ )?;
+
+ let inkscape_result = inkscape_command.wait()?;
+ assert!(inkscape_result.success());
+ let svgo_result = svgo_command.wait_with_output()?;
+ assert!(svgo_result.status.success());
+ let result = String::from_utf8(svgo_result.stdout)?;
+ Ok(result)
+}
+
+#[get("/")]
+fn index() -> &'static str {
+ "Hello, world!"
+}
+
+#[get("/render/<text>")]
+fn render(text: &str) -> Result<(ContentType, String), (Status, String)> {
+ match to_final_svg(text) {
+ Ok(svg) => Ok((ContentType::SVG, svg)),
+ Err(e) => Err((Status::InternalServerError, e.to_string())),
+ }
+}
+
+#[rocket::main]
+async fn main() -> Result<(), rocket::Error> {
+ let _rocket = rocket::build()
+ .mount("/", routes![index, render])
+ .launch()
+ .await?;
+
+ Ok(())
}