Migrate what bit of the yapper.py script there was to rust.
This commit is contained in:
416
Cargo.lock
generated
Normal file
416
Cargo.lock
generated
Normal file
@@ -0,0 +1,416 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
|
||||
dependencies = [
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||
|
||||
[[package]]
|
||||
name = "cutinews"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
"ron",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"log",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.177"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ron"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db09040cc89e461f1a265139777a2bde7f8d8c67c4936f700c63ce3e2904d468"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bitflags",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"rustversion",
|
||||
"wasm-bindgen-macro",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.62.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-link",
|
||||
"windows-result",
|
||||
"windows-strings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.59.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
29
Cargo.toml
Normal file
29
Cargo.toml
Normal file
@@ -0,0 +1,29 @@
|
||||
[package]
|
||||
name = "cutinews"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
|
||||
[dependencies]
|
||||
chrono = "0.4"
|
||||
ron = "0.11"
|
||||
|
||||
[dependencies.clap]
|
||||
version = "4.5"
|
||||
default-features = false
|
||||
features = [
|
||||
# From default features collection
|
||||
"error-context",
|
||||
"help",
|
||||
"std",
|
||||
"suggestions",
|
||||
"usage",
|
||||
|
||||
# Optional features
|
||||
"derive",
|
||||
"string",
|
||||
]
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0"
|
||||
features = ["derive"]
|
||||
163
src/blog.rs
Normal file
163
src/blog.rs
Normal file
@@ -0,0 +1,163 @@
|
||||
use crate::error;
|
||||
use chrono::NaiveDate;
|
||||
use ron::error::SpannedResult;
|
||||
use serde::{Deserialize, Deserializer, de::DeserializeOwned};
|
||||
use std::{fs::File, path::PathBuf};
|
||||
|
||||
const SANE_DATE_FORMAT: &str = "%Y-%m-%d";
|
||||
|
||||
pub static FALLBACK_META_PATH: std::sync::OnceLock<PathBuf> = std::sync::OnceLock::new();
|
||||
static FALLBACK_META: std::sync::OnceLock<MetaFallback> = std::sync::OnceLock::new();
|
||||
|
||||
/// Make sure to populate `FALLBACK_META_PATH` before constructing a `Meta`.
|
||||
///
|
||||
/// `MetaFallback` is the same as `Meta`, but without a `Default` impl.
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(default)]
|
||||
pub struct Meta {
|
||||
title: String,
|
||||
description: String,
|
||||
tags: Vec<String>,
|
||||
|
||||
site_name: String,
|
||||
locale: String,
|
||||
#[serde(rename = "type")]
|
||||
type_: String, // `type` is a keyword, this gets around that limitation.
|
||||
|
||||
authors: Vec<crate::og::Author>,
|
||||
date: Date,
|
||||
image: Option<Image>,
|
||||
}
|
||||
|
||||
impl Default for Meta {
|
||||
fn default() -> Self {
|
||||
// Get FALLBACK_META, loading it from FALLBACK_META_PATH if OnceLock not initialized.
|
||||
FALLBACK_META
|
||||
.get_or_init(|| {
|
||||
MetaFallback::try_from(FALLBACK_META_PATH.get().unwrap().to_owned())
|
||||
.expect("Failed to deserialize fallback_meta file")
|
||||
})
|
||||
.to_owned()
|
||||
.as_meta()
|
||||
}
|
||||
}
|
||||
|
||||
/// Same as `Meta`, but acts as the fallback for Meta's default values.
|
||||
///
|
||||
/// Not intended to be directly constructed; populate `FALLBACK_META_PATH`
|
||||
/// before constructing a `Meta`.
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct MetaFallback {
|
||||
title: String,
|
||||
description: String,
|
||||
tags: Vec<String>,
|
||||
|
||||
site_name: String,
|
||||
locale: String,
|
||||
#[serde(rename = "type")]
|
||||
type_: String, // `type` is a keyword, this gets around that limitation.
|
||||
|
||||
authors: Vec<crate::og::Author>,
|
||||
date: Date,
|
||||
image: Option<Image>,
|
||||
}
|
||||
|
||||
impl MetaFallback {
|
||||
fn as_meta(&self) -> Meta {
|
||||
// This is just to skip some `self.` spam.
|
||||
// There doesn't seem to be a better way to do this.
|
||||
let MetaFallback {
|
||||
title,
|
||||
description,
|
||||
tags,
|
||||
site_name,
|
||||
locale,
|
||||
type_,
|
||||
authors,
|
||||
date,
|
||||
image,
|
||||
} = self;
|
||||
|
||||
Meta {
|
||||
title: title.to_string(),
|
||||
description: description.to_string(),
|
||||
tags: tags.to_owned(),
|
||||
site_name: site_name.to_string(),
|
||||
locale: locale.to_string(),
|
||||
type_: type_.to_string(),
|
||||
authors: authors.to_owned(),
|
||||
date: date.to_owned(),
|
||||
image: image.to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn meta_try_from_file<T: DeserializeOwned>(file: File) -> SpannedResult<T> {
|
||||
use ron::extensions::Extensions;
|
||||
ron::Options::default()
|
||||
//.with_default_extension(Extensions::EXPLICIT_STRUCT_NAMES)
|
||||
.with_default_extension(Extensions::IMPLICIT_SOME)
|
||||
.with_default_extension(Extensions::UNWRAP_NEWTYPES)
|
||||
.with_default_extension(Extensions::UNWRAP_VARIANT_NEWTYPES)
|
||||
.from_reader(file)
|
||||
}
|
||||
|
||||
impl TryFrom<File> for Meta {
|
||||
type Error = error::MetaError;
|
||||
|
||||
fn try_from(file: File) -> Result<Self, Self::Error> {
|
||||
Ok(meta_try_from_file(file)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<File> for MetaFallback {
|
||||
type Error = error::MetaError;
|
||||
|
||||
fn try_from(file: File) -> Result<Self, Self::Error> {
|
||||
Ok(meta_try_from_file(file)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<PathBuf> for Meta {
|
||||
type Error = error::MetaError;
|
||||
|
||||
fn try_from(path: PathBuf) -> Result<Self, Self::Error> {
|
||||
Self::try_from(
|
||||
std::fs::OpenOptions::new()
|
||||
.read(true) // Just ensure that file opens read-only.
|
||||
.open(path.as_path())?,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<PathBuf> for MetaFallback {
|
||||
type Error = error::MetaError;
|
||||
|
||||
fn try_from(path: PathBuf) -> Result<Self, Self::Error> {
|
||||
Self::try_from(
|
||||
std::fs::OpenOptions::new()
|
||||
.read(true) // Just ensure that file opens read-only.
|
||||
.open(path.as_path())?,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[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/error.rs
Normal file
28
src/error.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use std::{fmt, io};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum MetaError {
|
||||
IOError(io::Error),
|
||||
RonSpanned(ron::error::SpannedError),
|
||||
}
|
||||
|
||||
impl fmt::Display for MetaError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::IOError(err) => write!(f, "{}", err),
|
||||
Self::RonSpanned(err) => write!(f, "{}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ron::error::SpannedError> for MetaError {
|
||||
fn from(error: ron::error::SpannedError) -> Self {
|
||||
Self::RonSpanned(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<io::Error> for MetaError {
|
||||
fn from(error: io::Error) -> Self {
|
||||
Self::IOError(error)
|
||||
}
|
||||
}
|
||||
37
src/main.rs
Normal file
37
src/main.rs
Normal file
@@ -0,0 +1,37 @@
|
||||
mod blog;
|
||||
mod error;
|
||||
mod og;
|
||||
|
||||
use clap::Parser;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::blog::Meta;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[clap(author, version, about)]
|
||||
struct Args {
|
||||
/// Path to blog root.
|
||||
#[arg(
|
||||
short = 'i',
|
||||
long,
|
||||
value_hint = clap::ValueHint::DirPath,
|
||||
default_value = format!("../test_tree/")
|
||||
)]
|
||||
blog_path: PathBuf,
|
||||
|
||||
#[arg(short, long, value_hint = clap::ValueHint::DirPath)]
|
||||
fallback_meta: PathBuf,
|
||||
|
||||
#[arg(short, long, value_hint = clap::ValueHint::DirPath)]
|
||||
single_meta: PathBuf,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let config = Args::parse();
|
||||
|
||||
blog::FALLBACK_META_PATH.get_or_init(|| config.fallback_meta);
|
||||
|
||||
let _meta = Meta::try_from(config.single_meta).expect("Failed to deserialize single_meta file");
|
||||
|
||||
println!("Loaded FallbackMeta");
|
||||
}
|
||||
46
src/og.rs
Normal file
46
src/og.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
use std::fmt;
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub enum Gender {
|
||||
Male,
|
||||
Female,
|
||||
}
|
||||
|
||||
impl fmt::Display for Gender {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:?}", self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<String> for Gender {
|
||||
fn into(self) -> String {
|
||||
self.to_string().to_lowercase()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub struct Author {
|
||||
name: Name,
|
||||
gender: Gender,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub enum Name {
|
||||
FirstOnly {
|
||||
first: String,
|
||||
},
|
||||
Full {
|
||||
first: String,
|
||||
last: String,
|
||||
},
|
||||
UserOnly {
|
||||
user: String,
|
||||
},
|
||||
All {
|
||||
first: String,
|
||||
last: String,
|
||||
user: String,
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user