Skip to content

Commit

Permalink
feat: Add Creation Support for JSON Format
Browse files Browse the repository at this point in the history
This introduces a new feature for the journal where a `serde`
JSON value can be used to create a new entry.  For the CLI tool
this is adds a new option of `--input` for `new`:

```bash
mdbook-journal new --input=json TOPIC
```
  • Loading branch information
benfalk committed Aug 17, 2024
1 parent a32aee0 commit ae2bd58
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mdbook-journal"
version = "0.2.2"
version = "0.2.3"
authors = ["Ben Falk <benjamin.falk@yahoo.com>"]
edition = "2021"
description = "journal plugin for mdBook"
Expand Down
32 changes: 27 additions & 5 deletions src/bin/mdbook-journal.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
//
// Generate a MD
//
use clap::{Parser, Subcommand};
use anyhow::Result;
use clap::{Parser, Subcommand, ValueEnum};
use mdbook::preprocess::Preprocessor;
use mdbook_journal::mdbook::preprocessor::{fetch_context, SimpleDirPreprocessor};
use mdbook_journal::{cli_entry, CliLoader, Journal};
use mdbook_journal::{cli_entry, CliLoader, EntryGenerationTrait, Journal};

fn main() -> anyhow::Result<()> {
fn main() -> Result<()> {
let args = Cli::parse();

match args.command.unwrap_or_default() {
Expand All @@ -22,11 +23,11 @@ fn main() -> anyhow::Result<()> {
// Do nothing for now; we support all
// render systems I'm pretty sure...
}
Command::New { topic } => {
Command::New { topic, input } => {
let config_file = std::fs::canonicalize(args.config)?;
let journal = Journal::<CliLoader>::load(config_file)?;
let topic = journal.with_topic(&topic)?;
let entry = &topic.generate_entry(cli_entry::std_io())?;
let entry = &topic.generate_entry(input.collect()?.as_ref())?;
let path = journal.persist_entry(entry)?;
println!("Entry Created: {}", path.display());
}
Expand Down Expand Up @@ -67,6 +68,8 @@ enum Command {
New {
/// topic to use
topic: String,
#[arg(short, long, value_enum, default_value = "interactive")]
input: TopicInput,
},
/// List out topics
Ls {
Expand All @@ -77,3 +80,22 @@ enum Command {
#[default]
Process,
}

#[derive(Debug, Clone, Default, Copy, ValueEnum)]
enum TopicInput {
#[default]
Interactive,
Json,
}

impl TopicInput {
fn collect(&self) -> Result<Box<dyn EntryGenerationTrait>> {
match self {
Self::Interactive => Ok(Box::new(cli_entry::std_io())),
Self::Json => {
let json: serde_json::Value = serde_json::from_reader(std::io::stdin())?;
Ok(Box::new(json))
}
}
}
}
2 changes: 1 addition & 1 deletion src/journal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ mod test {
.withf(|var| var.key() == "title")
.returning(|_| Ok(Some(MetaValue::String("Test Entry".to_owned()))));

let entry = topic.generate_entry(adapter)?;
let entry = topic.generate_entry(&adapter)?;

assert_eq!(entry.topic_name(), "code-blog");
assert_eq!(entry.created_at().year(), 2024);
Expand Down
6 changes: 2 additions & 4 deletions src/journal/topic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use path_mapping::PathMapping;
use template::Template;

pub mod cli_entry;
pub mod json_entry;

pub use builder::*;
pub use map::*;
Expand Down Expand Up @@ -63,10 +64,7 @@ impl Topic {
self.name.as_ref()
}

pub fn generate_entry<A>(&self, adapter: A) -> Result<Entry>
where
A: EntryGenerationTrait,
{
pub fn generate_entry(&self, adapter: &dyn EntryGenerationTrait) -> Result<Entry> {
let mut entry = Entry::builder(self.name());
entry = entry.created_at(adapter.created_at()?);

Expand Down
4 changes: 2 additions & 2 deletions src/journal/topic/cli_entry.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::prelude::*;

pub struct CliEntryGeneration {}
pub struct CliEntryGeneration;

pub fn std_io() -> CliEntryGeneration {
CliEntryGeneration {}
CliEntryGeneration
}

impl EntryGenerationTrait for CliEntryGeneration {
Expand Down
22 changes: 22 additions & 0 deletions src/journal/topic/json_entry.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use crate::prelude::*;
use serde_json::Value;

impl EntryGenerationTrait for Value {
fn collect_value(&self, variable: &Variable) -> Result<Option<MetaValue>> {
let val = self
.as_object()
.with_context(|| format!("reading input {:?}", self))?
.get(variable.key());

match val {
None => Ok(None),
Some(Value::Null) => Ok(None),
Some(Value::String(val)) => Ok(Some(MetaValue::String(val.to_owned()))),
Some(Value::Bool(true)) => Ok(Some(MetaValue::String("true".into()))),
Some(Value::Bool(false)) => Ok(Some(MetaValue::String("false".into()))),
Some(Value::Number(num)) => Ok(Some(MetaValue::String(num.to_string()))),
Some(Value::Object(_)) => bail!("invalid value of object"),
Some(Value::Array(_)) => bail!("invalid value of array"),
}
}
}

0 comments on commit ae2bd58

Please sign in to comment.