use serde::Serialize; use std::fs::DirEntry; use std::{io, env}; use rocket::serde::json::Json; #[derive(Serialize)] pub struct Category { name: String, // NOTE: this is simply a URI pathname // EXAMPLE: /thumbnail//.thumbnail.png thumbnail: String } #[derive(Serialize)] struct List { categories: Vec } fn get_category_dirs(path: &str) -> std::io::Result> { let path = std::path::Path::new(path); if !path.is_dir() { let e = io::Error::new(io::ErrorKind::NotFound, "Unable to open"); return Err(e); } let mut ret: Vec = Vec::new(); for entry in std::fs::read_dir(path)? { if let Ok(entry) = entry { ret.push(entry) } } return Ok(ret); } #[get("/categories")] pub fn list() -> Json> { // WARN: misconfigured servers are just going to get shafted and serve up // a tonne of 500's let dir = match env::var("CLIPS_DIR") { Ok(val) => val, Err(_) => "/media/clips/".to_string() }; let mut cats: Vec = Vec::new(); if let Ok(dirs) = get_category_dirs(&dir) { // Let's just assume that each item in this directory is a folder // That way we can do this blindly without 9999 allocs for d in dirs { let name = d.file_name().to_string_lossy().to_string(); let thumbnail = format!("/thumbnail/{}/category-thumbnail.jpg", name); cats.push(Category {name, thumbnail}); } } Json(cats) }