Compare commits

...

3 Commits

Author SHA1 Message Date
Olivia Brooks
5247a52497 Prepare for Lockfile saving; Clean up. 2025-10-15 12:42:21 -04:00
Olivia Brooks
eb0237792c Clean up. 2025-10-15 12:41:44 -04:00
Olivia Brooks
90ceb2124e Module restructure 2025-10-15 12:40:52 -04:00
10 changed files with 182 additions and 53 deletions

77
Cargo.lock generated
View File

@@ -156,8 +156,15 @@ dependencies = [
"markdown",
"ron",
"serde",
"toml",
]
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "fdeflate"
version = "0.3.7"
@@ -189,6 +196,12 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
[[package]]
name = "hashbrown"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
[[package]]
name = "heck"
version = "0.5.0"
@@ -245,6 +258,16 @@ dependencies = [
"quick-error",
]
[[package]]
name = "indexmap"
version = "2.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "js-sys"
version = "0.3.81"
@@ -406,6 +429,15 @@ dependencies = [
"syn",
]
[[package]]
name = "serde_spanned"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392"
dependencies = [
"serde_core",
]
[[package]]
name = "shlex"
version = "1.3.0"
@@ -435,6 +467,45 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "toml"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8"
dependencies = [
"indexmap",
"serde_core",
"serde_spanned",
"toml_datetime",
"toml_parser",
"toml_writer",
"winnow",
]
[[package]]
name = "toml_datetime"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533"
dependencies = [
"serde_core",
]
[[package]]
name = "toml_parser"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e"
dependencies = [
"winnow",
]
[[package]]
name = "toml_writer"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2"
[[package]]
name = "unicode-id"
version = "0.3.6"
@@ -565,6 +636,12 @@ dependencies = [
"windows-link",
]
[[package]]
name = "winnow"
version = "0.7.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
[[package]]
name = "zune-core"
version = "0.4.12"

View File

@@ -9,6 +9,7 @@ chrono = "0.4"
glob = "0.3.3"
markdown = "1.0.0"
ron = "0.11"
toml = "0.9.8"
[dependencies.clap]
version = "4.5"

View File

@@ -1,17 +1,28 @@
use crate::error;
use std;
use std::fs::File;
use std::path::{Path, PathBuf};
use std::{
fs::File,
path::{Path, PathBuf},
};
use chrono::NaiveDate;
use ron::error::SpannedResult;
use serde::{Deserialize, Deserializer, de::DeserializeOwned};
use serde::{Deserialize, de::DeserializeOwned};
const SANE_DATE_FORMAT: &str = "%Y-%m-%d";
use super::{
og,
res::{Date, Image},
};
use crate::error;
pub static FALLBACK_META_PATH: std::sync::OnceLock<PathBuf> = std::sync::OnceLock::new();
static FALLBACK_META: std::sync::OnceLock<MetaFallback> = std::sync::OnceLock::new();
/// Fallback Meta Setup
pub fn load_fb_meta<P: AsRef<Path>>(path: P) {
FALLBACK_META_PATH.get_or_init(|| path.as_ref().to_path_buf());
// Trigger OnceLock loading of fallback_meta path.
Meta::default();
}
/// Make sure to populate `FALLBACK_META_PATH` before constructing a `Meta`.
///
/// `MetaFallback` is the same as `Meta`, but without a `Default` impl.
@@ -24,10 +35,15 @@ pub struct Meta {
site_name: String,
locale: String,
// `type` is a keyword, this gets around that limitation.
//
// Trailing underscore is apparently a semi-common practice for this, as
// prefixed underscore is reserved by the compiler to indicate
// intentionally unused assignments.
#[serde(rename = "type")]
type_: String, // `type` is a keyword, this gets around that limitation.
type_: String,
authors: Vec<crate::og::Author>,
authors: Vec<og::Author>,
date: Date,
image: Option<Image>,
}
@@ -60,7 +76,7 @@ struct MetaFallback {
#[serde(rename = "type")]
type_: String, // `type` is a keyword, this gets around that limitation.
authors: Vec<crate::og::Author>,
authors: Vec<og::Author>,
date: Date,
image: Option<Image>,
}
@@ -105,6 +121,7 @@ fn meta_try_from_file<T: DeserializeOwned>(file: File) -> SpannedResult<T> {
.from_reader(file)
}
// TryFrom<File>
impl TryFrom<File> for Meta {
type Error = error::MetaError;
@@ -121,6 +138,7 @@ impl TryFrom<File> for MetaFallback {
}
}
// TryFrom<&Path>
impl TryFrom<&Path> for Meta {
type Error = error::MetaError;
@@ -144,23 +162,3 @@ impl TryFrom<&Path> for MetaFallback {
)
}
}
#[derive(Clone, Debug, Deserialize)]
pub struct Image(String);
#[derive(Clone, Debug, Deserialize, Default)]
#[serde(default)]
pub struct Date {
#[serde(deserialize_with = "naive_date_from_str")]
posted: NaiveDate,
#[serde(deserialize_with = "naive_date_from_str")]
modified: NaiveDate,
}
fn naive_date_from_str<'de, D>(deserializer: D) -> Result<NaiveDate, D::Error>
where
D: Deserializer<'de>,
{
NaiveDate::parse_from_str(Deserialize::deserialize(deserializer)?, SANE_DATE_FORMAT)
.map_err(serde::de::Error::custom)
}

6
src/blog/mod.rs Normal file
View File

@@ -0,0 +1,6 @@
mod meta;
pub mod og;
mod res;
#[allow(unused_imports)]
pub use meta::{FALLBACK_META_PATH, Meta, load_fb_meta};

View File

@@ -20,12 +20,14 @@ impl Into<String> for Gender {
}
}
#[allow(dead_code)]
#[derive(Clone, Debug, Deserialize)]
pub struct Author {
name: Name,
gender: Gender,
}
#[allow(dead_code)]
#[derive(Clone, Debug, Deserialize)]
pub enum Name {
FirstOnly {

25
src/blog/res.rs Normal file
View File

@@ -0,0 +1,25 @@
use chrono::NaiveDate;
use serde::{Deserialize, Deserializer};
const SANE_DATE_FORMAT: &str = "%Y-%m-%d";
#[allow(dead_code)]
#[derive(Clone, Debug, Deserialize)]
pub struct Image(String);
#[derive(Clone, Debug, Deserialize, Default)]
#[serde(default)]
pub struct Date {
#[serde(deserialize_with = "naive_date_from_str")]
posted: NaiveDate,
#[serde(deserialize_with = "naive_date_from_str")]
modified: NaiveDate,
}
fn naive_date_from_str<'de, D>(deserializer: D) -> Result<NaiveDate, D::Error>
where
D: Deserializer<'de>,
{
NaiveDate::parse_from_str(Deserialize::deserialize(deserializer)?, SANE_DATE_FORMAT)
.map_err(serde::de::Error::custom)
}

View File

@@ -8,11 +8,23 @@ pub struct Cli {
#[command(subcommand)]
pub command: Commands,
#[arg(value_hint = clap::ValueHint::DirPath, default_value = format!("./target"))]
#[arg(value_hint = clap::ValueHint::DirPath, default_value = "./target")]
target_dir: PathBuf,
}
#[derive(Debug, Subcommand)]
impl Cli {
fn get_target_dir(&self) -> PathBuf {
match self.command.clone() {
Commands::Clean => self.target_dir.to_owned(),
Commands::Build { lockfile, .. } => lockfile.into(),
Commands::Refresh { lockfile, .. } => lockfile.into(),
Commands::Update { lockfile } => lockfile.into(),
_ => panic!("New cli::Commands variant not accounted for."),
}
}
}
#[derive(Debug, Subcommand, Clone, PartialEq)]
pub enum Commands {
#[command(arg_required_else_help = true)]
Build {
@@ -60,13 +72,13 @@ pub enum RefreshScope {
All, // Both of the above
}
#[derive(Debug, Args)]
#[derive(Debug, Args, Clone, PartialEq)]
pub struct LockfileAccess {
/// Path to blog root for batch updating.
#[arg(
long,
value_hint = clap::ValueHint::DirPath,
default_value = format!("./")
default_value = "./"
)]
post_tree: PathBuf,
@@ -75,7 +87,13 @@ pub struct LockfileAccess {
short,
long,
value_hint = clap::ValueHint::DirPath,
default_value = format!("cutinews.lock")
default_value = "cutinews.lock"
)]
lock_file: PathBuf,
}
impl Into<PathBuf> for LockfileAccess {
fn into(self) -> PathBuf {
return PathBuf::from(format!("{:?}{:?}", self.post_tree, self.lock_file));
}
}

View File

@@ -4,7 +4,12 @@ use std::path::Path;
use image::ImageReader;
use markdown;
pub fn to_webp(path: &Path) -> Result<(), Box<dyn std::error::Error>> {
pub fn to_webp<P>(path: P) -> Result<(), Box<dyn std::error::Error>>
where
P: AsRef<Path>,
{
let path = path.as_ref();
ImageReader::open(path)?.decode()?.save(format!(
"{}.webp",
path.file_stem().unwrap().to_str().unwrap()
@@ -13,7 +18,10 @@ pub fn to_webp(path: &Path) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
pub fn md_to_html(path: &Path) -> Result<String, markdown::message::Message> {
pub fn md_to_html<P>(path: P) -> Result<String, markdown::message::Message>
where
P: AsRef<Path>,
{
let mut buf = String::new();
// Loading and Converting post.md to html

1
src/lock.rs Normal file
View File

@@ -0,0 +1 @@
pub struct LockFile {}

View File

@@ -2,17 +2,15 @@ mod blog;
mod cli;
mod convert;
mod error;
mod og;
mod lock;
use std::path::PathBuf;
use crate::blog::Meta;
use crate::cli::Commands;
use crate::blog::load_fb_meta;
use crate::cli::{Cli, Commands};
use clap::Parser;
fn main() {
let config = cli::Cli::parse();
let config = Cli::parse();
dbg!(&config);
@@ -23,12 +21,16 @@ fn main() {
meta,
post_md,
template_html,
} => (),
} => {
load_fb_meta(fallback_meta);
}
Commands::Update { lockfile } => (),
Commands::Refresh { lockfile, scope } => (),
Commands::Clean => (),
}
//println!("Loaded FallbackMeta");
/*
load_fb_meta(&config);
@@ -52,12 +54,3 @@ fn main() {
.expect("Failed to deserialize single_meta file");
*/
}
/// Fallback Meta Setup
fn load_fb_meta(path: PathBuf) {
blog::FALLBACK_META_PATH.get_or_init(|| path);
// Trigger OnceLock loading of fallback_meta path.
Meta::default();
println!("Loaded FallbackMeta");
}