Skip to content

Commit

Permalink
Improve generation
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeDoctorDE committed Dec 17, 2023
1 parent 0dae8ae commit b1ca558
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 48 deletions.
8 changes: 4 additions & 4 deletions api/src/models/asset.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use serde::{Deserialize, Serialize};
use crate::models::Named;

// Path: assets/{author}/{name}/asset.toml
// Path: content/{author}/{name}/asset.toml
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct Asset {
pub author : String,
pub name : String,
pub id : String,
pub tags : Vec<String>,
pub thumbnail_url : String,
pub preview_urls : Vec<String>,
pub thumbnail_url : Option<String>,
pub preview_urls : Option<Vec<String>>,
pub current_version : Version,
pub previous_versions : Vec<Version>,
pub summary : Option<String>,
Expand All @@ -28,7 +28,7 @@ pub struct Version {
pub blake3 : Option<String>,
}

// Path: assets/{author}/author.toml
// Path: content/{author}/author.toml
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct Author {
pub name : String,
Expand Down
64 changes: 30 additions & 34 deletions cli/src/directory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ pub enum ModelError {
IoError(#[from] io::Error),
#[error(transparent)]
TomlError(#[from] de::Error),
#[error("Model file not found")]
ModelFileNotFound,
#[error("Model file not found (expected {0:?})")]
ModelFileNotFound(Option<PathBuf>),
#[error("Model name not valid (expected {expected:?}, found {found:?})")]
NotValidName { expected: Option<String>, found: String },
}
Expand All @@ -29,13 +29,17 @@ pub trait ModelDirectory<T>
fn file_path(&self) -> PathBuf {
self.data_path().join("config.toml")
}
fn content_path(&self) -> PathBuf {
self.data_path().join("content")
}
fn name(&self) -> Option<String>;
fn model(&self) -> Result<T, ModelError> {
let file = self.file_path();
if !self.is_valid() {
return Err(ModelFileNotFound);
return Err(ModelFileNotFound(Some(file)));
}

let data = std::fs::read_to_string(self.file_path())?;
let data = std::fs::read_to_string(file)?;
let model: T = toml::from_str(&data)?;
if self.name().map(|name| name != model.name()).unwrap_or(false) {
return Err(ModelError::NotValidName {
Expand All @@ -62,20 +66,27 @@ impl RepositoryDirectory {
}

pub fn authors(&self) -> Result<Vec<String>, io::Error> {
let mut assets = Vec::new();
for entry in self.data_path().read_dir()? {
let mut authors = Vec::new();
let content = self.content_path();
if !content.exists() {
return Ok(authors);
}
for entry in content.read_dir()? {
let Ok(entry) = entry else {
continue;
};
if !entry.path().is_dir() {
continue;
}
let path = entry.path();
let file_name = path.file_name().unwrap().to_str().unwrap().to_string();

if path.is_dir() {
assets.push(file_name);
authors.push(file_name);
}
}

Ok(assets)
Ok(authors)
}

pub fn author(&self, name: &str) -> AuthorDirectory {
Expand All @@ -98,7 +109,11 @@ pub struct AuthorDirectory<'a> (&'a RepositoryDirectory, String);
impl AuthorDirectory<'_> {
pub fn assets(&self) -> Result<Vec<String>, io::Error> {
let mut assets = Vec::new();
for entry in self.data_path().read_dir()? {
let path = self.assets_path();
if !path.exists() {
return Ok(assets);
}
for entry in path.read_dir()? {
let Ok(entry) = entry else {
continue;
};
Expand All @@ -113,14 +128,18 @@ impl AuthorDirectory<'_> {
Ok(assets)
}

pub fn assets_path(&self) -> PathBuf {
self.data_path().join("assets")
}

pub fn asset(&self, name: &str) -> AssetDirectory {
AssetDirectory(self, name.to_owned())
}
}

impl ModelDirectory<Author> for AuthorDirectory<'_> {
fn data_path(&self) -> PathBuf {
self.0.data_path().join(&self.1)
self.0.content_path().join(&self.1)
}

fn name(&self) -> Option<String> {
Expand All @@ -130,32 +149,9 @@ impl ModelDirectory<Author> for AuthorDirectory<'_> {

pub struct AssetDirectory<'a> (&'a AuthorDirectory<'a>, String);

impl AssetDirectory<'_> {
pub fn assets_path(&self) -> PathBuf {
self.data_path().join("assets")
}

pub fn is_valid(&self) -> bool {
self.data_path().is_dir()
}

pub fn get_asset_path(&self, name: &str) -> Option<PathBuf> {
let path = self.assets_path().join(name);
// If path is file and assets_path is parent of path
if !path.is_file() || !path.starts_with(self.assets_path()) {
return None;
}
Some(path)
}

pub fn has_asset(&self, name: &str) -> bool {
self.get_asset_path(name).is_some()
}
}

impl ModelDirectory<Asset> for AssetDirectory<'_> {
fn data_path(&self) -> PathBuf {
self.0.data_path().join(&self.1)
self.0.assets_path().join(&self.1)
}

fn name(&self) -> Option<String> {
Expand Down
31 changes: 24 additions & 7 deletions cli/src/docs.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::{fs, path::Path, io::{self, Write}};
use std::{fs, path::Path, io::Write};

use handlebars::{Handlebars, TemplateError, Context};
use handlebars::{Handlebars, TemplateError};
use luna_api::models::RepositoryData;
use serde_json::json;
use serde_json::{json, Value};
use thiserror::Error;
use rust_embed::RustEmbed;

Expand Down Expand Up @@ -31,6 +31,18 @@ pub fn generate_docs(data: &RepositoryData, output : String) -> Result<(), DocsE
render_static("index", data, &hb, &output)?;
render_static("search", data, &hb, &output)?;


for author in data.authors.iter() {
fs::create_dir_all(format!("{}/{}", output, author.name))?;
}
for asset in data.assets.iter() {
let context: &Value = &json!({
"asset": asset,
"info": data.info
});
render_dynamic("asset", &format!("{}/{}", asset.author, asset.name), &hb, &output, context)?;
}

for file in Public::iter() {
let path = file.as_ref();
let content = Public::get(path).unwrap();
Expand All @@ -47,11 +59,16 @@ pub fn generate_docs(data: &RepositoryData, output : String) -> Result<(), DocsE
}

fn render_static(name : &str, data: &RepositoryData, hb: &Handlebars, output : &str) -> Result<(), DocsError> {
let context = &json!({
let context: &Value = &json!({
"info": data.info
});
let rendered = hb.render(&format!("templates/{}.hbs",name), context)?;
std::fs::write(format!("{}/{}.html", output, name), rendered)?;
println!("Rendered {} at {}/{}.html", name, output, name);
render_dynamic(name, name, hb, output, context)
}

fn render_dynamic(name : &str, output_name : &str, hb: &Handlebars, output : &str, context: &Value) -> Result<(), DocsError> {
let rendered = hb.render(&format!("templates/{}.hbs",name), &context)?;
fs::write(format!("{}/{}.html", output, output_name), rendered)?;
println!("Rendered {} at {}/{}.html", name, output, output_name);
Ok(())

}
9 changes: 6 additions & 3 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ fn main() {
}

fn docs(path: Option<String>, index: Option<String>) {
let index = index.unwrap_or(String::from("index.json"));
let index = index.unwrap_or(format!("{}/index.json", path.clone().unwrap_or(".".to_string())));
let data = RepositoryData::from_index(
std::fs::read_to_string(&index)
.expect("Could not read index file")
.expect(&format!("Could not read index file {}", &index))
.as_ref(),
)
.expect("Could not parse index file");
Expand All @@ -76,7 +76,10 @@ fn docs(path: Option<String>, index: Option<String>) {
}

fn generate(path: Option<String>) {
let path = path.unwrap_or(String::from("index.json"));
if let Some(path) = &path {
std::fs::create_dir_all(&path).expect("Could not create directory");
}
let path = format!("{}/index.json", path.unwrap_or(".".to_string()));
let directory = directory::RepositoryDirectory::new(None);
match { directory.generate_index() } {
Ok(data) => {
Expand Down
4 changes: 4 additions & 0 deletions example/content/codedoctor/assets/testasset/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name = "testasset"
author = "obiwan"
id = "LEL"
tags = ["test", "asset"]
3 changes: 3 additions & 0 deletions example/content/codedoctor/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name = "codedoctor"
email = "[email protected]"
links = ["https://github.com/CodeDoctorDE"]

0 comments on commit b1ca558

Please sign in to comment.