Compare commits
3 Commits
3937777255
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5247a52497 | ||
|
|
eb0237792c | ||
|
|
90ceb2124e |
77
Cargo.lock
generated
77
Cargo.lock
generated
@@ -156,8 +156,15 @@ dependencies = [
|
|||||||
"markdown",
|
"markdown",
|
||||||
"ron",
|
"ron",
|
||||||
"serde",
|
"serde",
|
||||||
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fdeflate"
|
name = "fdeflate"
|
||||||
version = "0.3.7"
|
version = "0.3.7"
|
||||||
@@ -189,6 +196,12 @@ version = "0.3.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
|
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@@ -245,6 +258,16 @@ dependencies = [
|
|||||||
"quick-error",
|
"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]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.81"
|
version = "0.3.81"
|
||||||
@@ -406,6 +429,15 @@ dependencies = [
|
|||||||
"syn",
|
"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]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
@@ -435,6 +467,45 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"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]]
|
[[package]]
|
||||||
name = "unicode-id"
|
name = "unicode-id"
|
||||||
version = "0.3.6"
|
version = "0.3.6"
|
||||||
@@ -565,6 +636,12 @@ dependencies = [
|
|||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.7.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zune-core"
|
name = "zune-core"
|
||||||
version = "0.4.12"
|
version = "0.4.12"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ chrono = "0.4"
|
|||||||
glob = "0.3.3"
|
glob = "0.3.3"
|
||||||
markdown = "1.0.0"
|
markdown = "1.0.0"
|
||||||
ron = "0.11"
|
ron = "0.11"
|
||||||
|
toml = "0.9.8"
|
||||||
|
|
||||||
[dependencies.clap]
|
[dependencies.clap]
|
||||||
version = "4.5"
|
version = "4.5"
|
||||||
|
|||||||
@@ -1,17 +1,28 @@
|
|||||||
use crate::error;
|
use std::{
|
||||||
use std;
|
fs::File,
|
||||||
use std::fs::File;
|
path::{Path, PathBuf},
|
||||||
use std::path::{Path, PathBuf};
|
};
|
||||||
|
|
||||||
use chrono::NaiveDate;
|
|
||||||
use ron::error::SpannedResult;
|
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();
|
pub static FALLBACK_META_PATH: std::sync::OnceLock<PathBuf> = std::sync::OnceLock::new();
|
||||||
static FALLBACK_META: std::sync::OnceLock<MetaFallback> = 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`.
|
/// Make sure to populate `FALLBACK_META_PATH` before constructing a `Meta`.
|
||||||
///
|
///
|
||||||
/// `MetaFallback` is the same as `Meta`, but without a `Default` impl.
|
/// `MetaFallback` is the same as `Meta`, but without a `Default` impl.
|
||||||
@@ -24,10 +35,15 @@ pub struct Meta {
|
|||||||
|
|
||||||
site_name: String,
|
site_name: String,
|
||||||
locale: 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")]
|
#[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,
|
date: Date,
|
||||||
image: Option<Image>,
|
image: Option<Image>,
|
||||||
}
|
}
|
||||||
@@ -60,7 +76,7 @@ struct MetaFallback {
|
|||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
type_: String, // `type` is a keyword, this gets around that limitation.
|
type_: String, // `type` is a keyword, this gets around that limitation.
|
||||||
|
|
||||||
authors: Vec<crate::og::Author>,
|
authors: Vec<og::Author>,
|
||||||
date: Date,
|
date: Date,
|
||||||
image: Option<Image>,
|
image: Option<Image>,
|
||||||
}
|
}
|
||||||
@@ -105,6 +121,7 @@ fn meta_try_from_file<T: DeserializeOwned>(file: File) -> SpannedResult<T> {
|
|||||||
.from_reader(file)
|
.from_reader(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TryFrom<File>
|
||||||
impl TryFrom<File> for Meta {
|
impl TryFrom<File> for Meta {
|
||||||
type Error = error::MetaError;
|
type Error = error::MetaError;
|
||||||
|
|
||||||
@@ -121,6 +138,7 @@ impl TryFrom<File> for MetaFallback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TryFrom<&Path>
|
||||||
impl TryFrom<&Path> for Meta {
|
impl TryFrom<&Path> for Meta {
|
||||||
type Error = error::MetaError;
|
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
6
src/blog/mod.rs
Normal 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};
|
||||||
@@ -20,12 +20,14 @@ impl Into<String> for Gender {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
pub struct Author {
|
pub struct Author {
|
||||||
name: Name,
|
name: Name,
|
||||||
gender: Gender,
|
gender: Gender,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
pub enum Name {
|
pub enum Name {
|
||||||
FirstOnly {
|
FirstOnly {
|
||||||
25
src/blog/res.rs
Normal file
25
src/blog/res.rs
Normal 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)
|
||||||
|
}
|
||||||
28
src/cli.rs
28
src/cli.rs
@@ -8,11 +8,23 @@ pub struct Cli {
|
|||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
pub command: Commands,
|
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,
|
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 {
|
pub enum Commands {
|
||||||
#[command(arg_required_else_help = true)]
|
#[command(arg_required_else_help = true)]
|
||||||
Build {
|
Build {
|
||||||
@@ -60,13 +72,13 @@ pub enum RefreshScope {
|
|||||||
All, // Both of the above
|
All, // Both of the above
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Args)]
|
#[derive(Debug, Args, Clone, PartialEq)]
|
||||||
pub struct LockfileAccess {
|
pub struct LockfileAccess {
|
||||||
/// Path to blog root for batch updating.
|
/// Path to blog root for batch updating.
|
||||||
#[arg(
|
#[arg(
|
||||||
long,
|
long,
|
||||||
value_hint = clap::ValueHint::DirPath,
|
value_hint = clap::ValueHint::DirPath,
|
||||||
default_value = format!("./")
|
default_value = "./"
|
||||||
)]
|
)]
|
||||||
post_tree: PathBuf,
|
post_tree: PathBuf,
|
||||||
|
|
||||||
@@ -75,7 +87,13 @@ pub struct LockfileAccess {
|
|||||||
short,
|
short,
|
||||||
long,
|
long,
|
||||||
value_hint = clap::ValueHint::DirPath,
|
value_hint = clap::ValueHint::DirPath,
|
||||||
default_value = format!("cutinews.lock")
|
default_value = "cutinews.lock"
|
||||||
)]
|
)]
|
||||||
lock_file: PathBuf,
|
lock_file: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Into<PathBuf> for LockfileAccess {
|
||||||
|
fn into(self) -> PathBuf {
|
||||||
|
return PathBuf::from(format!("{:?}{:?}", self.post_tree, self.lock_file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,12 @@ use std::path::Path;
|
|||||||
use image::ImageReader;
|
use image::ImageReader;
|
||||||
use markdown;
|
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!(
|
ImageReader::open(path)?.decode()?.save(format!(
|
||||||
"{}.webp",
|
"{}.webp",
|
||||||
path.file_stem().unwrap().to_str().unwrap()
|
path.file_stem().unwrap().to_str().unwrap()
|
||||||
@@ -13,7 +18,10 @@ pub fn to_webp(path: &Path) -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
Ok(())
|
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();
|
let mut buf = String::new();
|
||||||
|
|
||||||
// Loading and Converting post.md to html
|
// Loading and Converting post.md to html
|
||||||
|
|||||||
1
src/lock.rs
Normal file
1
src/lock.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pub struct LockFile {}
|
||||||
25
src/main.rs
25
src/main.rs
@@ -2,17 +2,15 @@ mod blog;
|
|||||||
mod cli;
|
mod cli;
|
||||||
mod convert;
|
mod convert;
|
||||||
mod error;
|
mod error;
|
||||||
mod og;
|
mod lock;
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use crate::blog::load_fb_meta;
|
||||||
|
use crate::cli::{Cli, Commands};
|
||||||
use crate::blog::Meta;
|
|
||||||
use crate::cli::Commands;
|
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let config = cli::Cli::parse();
|
let config = Cli::parse();
|
||||||
|
|
||||||
dbg!(&config);
|
dbg!(&config);
|
||||||
|
|
||||||
@@ -23,12 +21,16 @@ fn main() {
|
|||||||
meta,
|
meta,
|
||||||
post_md,
|
post_md,
|
||||||
template_html,
|
template_html,
|
||||||
} => (),
|
} => {
|
||||||
|
load_fb_meta(fallback_meta);
|
||||||
|
}
|
||||||
Commands::Update { lockfile } => (),
|
Commands::Update { lockfile } => (),
|
||||||
Commands::Refresh { lockfile, scope } => (),
|
Commands::Refresh { lockfile, scope } => (),
|
||||||
Commands::Clean => (),
|
Commands::Clean => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//println!("Loaded FallbackMeta");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
load_fb_meta(&config);
|
load_fb_meta(&config);
|
||||||
@@ -52,12 +54,3 @@ fn main() {
|
|||||||
.expect("Failed to deserialize single_meta file");
|
.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");
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user