feat: sending out svgs
This commit is contained in:
parent
3d7bfd490a
commit
545e9bdabe
2 changed files with 78 additions and 21 deletions
59
src/icons.rs
Normal file
59
src/icons.rs
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
use std::{env, ffi::OsString, fs};
|
||||||
|
|
||||||
|
const ICON_FILE_EXTENSION: &'static str = ".svg";
|
||||||
|
pub const ICON_FILE_EXTENSION_LEN: usize = ICON_FILE_EXTENSION.len();
|
||||||
|
|
||||||
|
pub struct Icons {
|
||||||
|
icons_dir_path: String,
|
||||||
|
icon_filenames: Vec<OsString>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Icons {
|
||||||
|
/// Build the Icons (handler) struct
|
||||||
|
///
|
||||||
|
/// Returns a result with the Icons struct or an error message
|
||||||
|
pub fn build() -> Result<Self, &'static str> {
|
||||||
|
let icons_dir_arg = env::args()
|
||||||
|
.nth(1)
|
||||||
|
.unwrap_or(String::from("vendor/lucide/icons"));
|
||||||
|
|
||||||
|
let icon_dir = match fs::read_dir(&icons_dir_arg) {
|
||||||
|
Ok(dir) => dir,
|
||||||
|
Err(_) => return Err("Failed to read icon directory"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let icon_filenames: Vec<_> = icon_dir
|
||||||
|
.map(|entry| entry.unwrap().file_name())
|
||||||
|
.filter(|entry| entry.to_str().unwrap_or("").ends_with(".svg"))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(Icons {
|
||||||
|
icons_dir_path: icons_dir_arg,
|
||||||
|
icon_filenames,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_filename(&self, icon: &str) -> bool {
|
||||||
|
self.icon_filenames.contains(&OsString::from(icon))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_iconname(&self, icon: &str) -> bool {
|
||||||
|
self.icon_filenames
|
||||||
|
.iter()
|
||||||
|
.find(|&i| match i.to_str() {
|
||||||
|
Some(i) => &i[..i.len() - ICON_FILE_EXTENSION_LEN] == icon,
|
||||||
|
None => false,
|
||||||
|
})
|
||||||
|
.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icons_len(&self) -> usize {
|
||||||
|
self.icon_filenames.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_icon(&self, icon: &str) -> Option<Vec<u8>> {
|
||||||
|
let icon_path = format!("{}/{}.svg", self.icons_dir_path, icon);
|
||||||
|
println!("Reading icon: {}", icon_path);
|
||||||
|
fs::read(icon_path).ok()
|
||||||
|
}
|
||||||
|
}
|
40
src/main.rs
40
src/main.rs
|
@ -1,29 +1,15 @@
|
||||||
use std::{env, ffi::OsString, fs, net::TcpListener, process};
|
use std::{ffi::OsString, fs, net::TcpListener, process};
|
||||||
|
|
||||||
use ctrlc;
|
use ctrlc;
|
||||||
use http::responses::{Response, Body};
|
use http::responses::{Body, Response};
|
||||||
|
|
||||||
mod handlers;
|
mod handlers;
|
||||||
mod http;
|
mod http;
|
||||||
|
mod icons;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("luciders starting...");
|
println!("luciders starting...");
|
||||||
|
|
||||||
let icons_dir_arg = env::args_os()
|
|
||||||
.nth(1)
|
|
||||||
.unwrap_or(OsString::from("vendor/lucide/icons"));
|
|
||||||
|
|
||||||
println!("Using icons from: {:?}", icons_dir_arg);
|
|
||||||
|
|
||||||
let icon_filenames: Vec<_> = fs::read_dir(icons_dir_arg)
|
|
||||||
.unwrap_or_else(|_| fatal("Failed to read icons directory! Does the path exist?"))
|
|
||||||
.map(|entry| entry.unwrap_or_else(|_| fatal("Failed to read icon entry")))
|
|
||||||
.map(|entry| entry.file_name())
|
|
||||||
.filter(|entry| entry.to_str().unwrap_or("").ends_with(".svg"))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
println!("Found {} icons", icon_filenames.len());
|
|
||||||
|
|
||||||
let listener =
|
let listener =
|
||||||
TcpListener::bind("[::]:7878").unwrap_or_else(|_| fatal("Failed to bind to address"));
|
TcpListener::bind("[::]:7878").unwrap_or_else(|_| fatal("Failed to bind to address"));
|
||||||
|
|
||||||
|
@ -33,6 +19,11 @@ fn main() {
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|_| fatal("Failed to set termination signal handler"));
|
.unwrap_or_else(|_| fatal("Failed to set termination signal handler"));
|
||||||
|
|
||||||
|
let icons = match icons::Icons::build() {
|
||||||
|
Ok(icons) => icons,
|
||||||
|
Err(e) => fatal(e),
|
||||||
|
};
|
||||||
|
|
||||||
let mut handlers = handlers::Handlers::new();
|
let mut handlers = handlers::Handlers::new();
|
||||||
|
|
||||||
handlers.add_handler("/", |req| {
|
handlers.add_handler("/", |req| {
|
||||||
|
@ -43,21 +34,28 @@ fn main() {
|
||||||
Response::new(req, 200, Body::Static("OK - luciders is running"))
|
Response::new(req, 200, Body::Static("OK - luciders is running"))
|
||||||
});
|
});
|
||||||
|
|
||||||
handlers.add_handler("/icons/[icon].png", move |req| {
|
handlers.add_handler("/icons/[icon].svg", move |req| {
|
||||||
if req.method != "GET" {
|
if req.method != "GET" {
|
||||||
return Response::new(req, 405, Body::Static("Method Not Allowed"));
|
return Response::new(req, 405, Body::Static("Method Not Allowed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let icon_name = match req.url.get_path_segment(1) {
|
let icon_filename = match req.url.get_path_segment(1) {
|
||||||
Some(icon) => icon,
|
Some(icon) => icon,
|
||||||
None => return Response::new(req, 404, Body::Static("Icon Not Found")),
|
None => return Response::new(req, 404, Body::Static("Icon Not Found")),
|
||||||
};
|
};
|
||||||
|
|
||||||
if !icon_filenames.contains(&OsString::from(&icon_name[..icon_name.len() - 4])) {
|
let icon_name = &icon_filename[..icon_filename.len() - icons::ICON_FILE_EXTENSION_LEN];
|
||||||
|
|
||||||
|
if !icons.has_iconname(icon_name) {
|
||||||
return Response::new(req, 404, Body::Static("Icon Not Found"));
|
return Response::new(req, 404, Body::Static("Icon Not Found"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response::new(req, 200, Body::Static("Icon Not Found"));
|
let icon = match icons.get_icon(icon_name) {
|
||||||
|
Some(icon) => icon,
|
||||||
|
None => return Response::new(req, 500, Body::Static("Failed to read icon")),
|
||||||
|
};
|
||||||
|
|
||||||
|
return Response::new(req, 200, Body::Bytes(icon, "image/svg+xml"));
|
||||||
});
|
});
|
||||||
|
|
||||||
handlers.bind(listener);
|
handlers.bind(listener);
|
||||||
|
|
Loading…
Reference in a new issue