add rocket to create rest api

This commit is contained in:
lauchmelder 2025-03-04 12:43:51 +01:00
parent 4ba1abe786
commit ae8525b891
6 changed files with 1523 additions and 24 deletions

1443
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -3,10 +3,19 @@ name = "font-explorer"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[lib]
name = "fontloader"
path = "src/lib.rs"
[[bin]]
name = "webview"
path = "src/webview/main.rs"
[dependencies] [dependencies]
bincode = "1.3.3" bincode = "1.3.3"
bitfield = "0.19.0" bitfield = "0.19.0"
clap = { version = "4.5.21", features = ["derive"] } clap = { version = "4.5.21", features = ["derive"] }
log = "0.4.26" log = "0.4.26"
rocket = "0.5.1"
serde = { version = "1.0.215", features = ["derive", "serde_derive"] } serde = { version = "1.0.215", features = ["derive", "serde_derive"] }
simplelog = { version = "0.12.2", features = ["termcolor"] } simplelog = { version = "0.12.2", features = ["termcolor"] }

21
src/lib.rs Normal file
View file

@ -0,0 +1,21 @@
use std::error::Error;
use log::LevelFilter;
use simplelog::{ColorChoice, Config, TermLogger, TerminalMode};
pub mod font;
pub mod writer;
pub use font::Font;
pub use writer::SvgWriter;
pub fn init() -> Result<(), Box<dyn Error>> {
TermLogger::init(
LevelFilter::Debug,
Config::default(),
TerminalMode::Mixed,
ColorChoice::Auto
)?;
Ok(())
}

42
src/webview/main.rs Normal file
View file

@ -0,0 +1,42 @@
#[macro_use] extern crate rocket;
use std::{fs::File, sync::Mutex};
use fontloader::{writer::Visitor, Font, SvgWriter};
use rocket::{response::{content, status}, State};
struct SharedFont {
font: Mutex<Font>
}
#[get("/glyph/<glyph>")]
fn get_glyph(font: &State<SharedFont>, glyph: &str) -> status::Accepted<content::RawHtml<String>> {
let Some(char) = glyph.chars().next() else {
return status::Accepted(content::RawHtml("Please provide a char".into()));
};
let result = match font.font.lock().unwrap().get_data_for(char) {
Ok(result) => result,
Err(err) => return status::Accepted(content::RawHtml(err.to_string()))
};
let mut svg_buf = vec![];
SvgWriter::new(&mut svg_buf).write(&result);
status::Accepted(content::RawHtml(String::from_utf8(svg_buf).unwrap()))
}
#[launch]
fn rocket() -> _ {
let _ = fontloader::init();
let font = Font::new(File::open("Helvetica.ttf").unwrap());
let Ok(font) = font else {
let err = font.unwrap_err().to_string();
panic!("{err}");
};
rocket::build()
.manage(SharedFont { font: Mutex::from(font) })
.mount("/", routes![get_glyph])
}

View file

@ -4,21 +4,21 @@ use crate::font::{GlyphHeader, GlyphPoint, SplineElement};
use super::Visitor; use super::Visitor;
pub struct SvgWriter { pub struct SvgWriter<'a, W: Sized + Write> {
first_point: bool, first_point: bool,
writer: BufWriter<File>, writer: &'a mut W,
points: Vec<(i32, i32)>, points: Vec<(i32, i32)>,
control_points: Vec<(i32, i32)>, control_points: Vec<(i32, i32)>,
virtual_points: Vec<(i32, i32)> virtual_points: Vec<(i32, i32)>
} }
impl SvgWriter { impl<'a, W: Sized + Write> SvgWriter<'a, W> {
pub fn new(file: File) -> Self { pub fn new(out: &'a mut W) -> Self {
SvgWriter { SvgWriter {
first_point: true, first_point: true,
writer: BufWriter::new(file), writer: out,
points: vec![], points: vec![],
control_points: vec![], control_points: vec![],
virtual_points: vec![] virtual_points: vec![]
@ -26,7 +26,7 @@ impl SvgWriter {
} }
} }
impl SvgWriter { impl<'a, W: Sized + Write> SvgWriter<'a, W> {
fn handle_start_point(&mut self, point: &GlyphPoint) { fn handle_start_point(&mut self, point: &GlyphPoint) {
if self.first_point { if self.first_point {
write!(self.writer, "M{} {} ", point.x, -point.y); write!(self.writer, "M{} {} ", point.x, -point.y);
@ -40,14 +40,22 @@ impl SvgWriter {
} }
} }
fn write_points(writer: &mut BufWriter<File>, points: &Vec<(i32, i32)>, color: &'static str) { fn write_points(&mut self) {
for (x, y) in points { for (x, y) in &self.points {
write!(writer, "<circle cx=\"{x}\" cy=\"{y}\" r=\"10\" fill=\"{color}\" />"); write!(self.writer, "<circle cx=\"{x}\" cy=\"{y}\" r=\"10\" fill=\"red\" />");
}
for (x, y) in &self.control_points {
write!(self.writer, "<circle cx=\"{x}\" cy=\"{y}\" r=\"10\" fill=\"blue\" />");
}
for (x, y) in &self.virtual_points {
write!(self.writer, "<circle cx=\"{x}\" cy=\"{y}\" r=\"10\" fill=\"green\" />");
} }
} }
} }
impl Visitor for SvgWriter { impl<'a, W: Sized + Write> Visitor for SvgWriter<'a, W> {
fn write_prefix(&mut self, header: &GlyphHeader) { fn write_prefix(&mut self, header: &GlyphHeader) {
write!( write!(
self.writer, self.writer,
@ -90,9 +98,7 @@ impl Visitor for SvgWriter {
"\" style=\"fill:none; stroke:black; stroke-width:3;\" />" "\" style=\"fill:none; stroke:black; stroke-width:3;\" />"
); );
SvgWriter::write_points(&mut self.writer, &self.points, "red"); self.write_points();
SvgWriter::write_points(&mut self.writer, &self.control_points, "blue");
SvgWriter::write_points(&mut self.writer, &self.virtual_points, "green");
write!(self.writer, "</svg>"); write!(self.writer, "</svg>");
} }