diff --git a/Cargo.toml b/Cargo.toml index 5d32839..cfad095 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "Plenum-Bot" +name = "plenum_bot" version = "0.1.0" edition = "2021" @@ -21,3 +21,11 @@ serde = {version = "1.0.204", features = ["derive"]} serde_json = "1.0.122" colored = "2.1.0" nom = "7.1.3" + +[[bin]] +name = "Plenum-Bot" +path = "src/main.rs" + +[lib] +name = "cccron_lib" +path = "src/lib.rs" diff --git a/src/config_spec.rs b/src/config_spec.rs index 3365dd1..a4d838f 100644 --- a/src/config_spec.rs +++ b/src/config_spec.rs @@ -2,6 +2,7 @@ //! //! Per module that wants config fields, declare a //! ```rust +//! # use cccron_lib::config_spec::{CfgGroup, CfgField}; //! pub const CONFIG: CfgGroup<'static> = CfgGroup { //! name: "modname", // this will be the field name prefix in the KV store //! description: "what this module is for", @@ -17,7 +18,10 @@ //! and then in the main module, glue them all together and use them to populate defaults etc. //! //! ```rust +//! # use cccron_lib::config_spec::{self, CfgSpec}; +//! # use cccron_lib::key_value::KeyValueStore; //! # mod modname { +//! # use cccron_lib::config_spec::{CfgGroup, CfgField}; //! # pub const CONFIG: CfgGroup<'static> = CfgGroup { //! # name: "modname", // this will be the field name prefix in the KV store //! # description: "what this module is for", @@ -35,12 +39,15 @@ //! // etc. //! ], //! }; +//! # fn main() -> rusqlite::Result<()> { //! // open a config file somewhere (we use a dummy to not cause side-effects) //! let config = KeyValueStore::new_dummy()?; //! // always: -//! CONFIG_SPEC.populate_defaults(&config); +//! config_spec::populate_defaults(&CONFIG_SPEC, &config); //! // (and then defaults will be set:) //! assert_eq!( config.get("modname-user").unwrap(), "xyzzy" ); +//! # Ok(()) +//! # } //! ``` //! //! ```ignore diff --git a/src/hedgedoc.rs b/src/hedgedoc.rs index edd8e77..a8c8f6d 100644 --- a/src/hedgedoc.rs +++ b/src/hedgedoc.rs @@ -115,6 +115,8 @@ pub fn summarize(pad_content: String) -> String { } /// For the config, make a new pad ID (by actually making a pad.) -fn make_pad_id(_key: &str, config: &crate::KV, is_dry_run: bool) -> Result> { +fn make_pad_id( + _key: &str, config: &crate::key_value::KeyValueStore, is_dry_run: bool, +) -> Result> { HedgeDoc::new(&config.get("hedgedoc-server-url").unwrap(), is_dry_run).create_pad() } diff --git a/src/key_value.rs b/src/key_value.rs index 07c2171..f840432 100644 --- a/src/key_value.rs +++ b/src/key_value.rs @@ -6,6 +6,7 @@ //! ``` //! //! ``` +//! # use cccron_lib::key_value::KeyValueStore; //! # let cfg = KeyValueStore::new_dummy()?; //! // Ensure defaults exist. (Do this early, this function panics on error.) //! cfg.default( "foo", "bar" ); @@ -13,11 +14,12 @@ //! // Normal use after that. //! let foo = cfg.get( "foo" ).unwrap(); //! let baz = &cfg["baz"]; // shorthand that LEAKS the string and panics on error -//! let asdf = cfg.get( "asdf" ).unwrap_or_default( "abc" ); +//! let asdf = cfg.get( "asdf" ).unwrap_or( "abc".to_string() ); //! cfg.set( "fnord", "23" )?; //! cfg.delete( "foo" )?; //! // If any writes failed, this flag will be set and the data got logged to stderr. //! let all_ok = !cfg.has_errors(); +//! # Ok::<(),rusqlite::Error>(()) //! ``` use colored::Colorize; diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..4b27f86 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,18 @@ +pub mod config_spec; +pub mod date; +pub mod email; +pub mod hedgedoc; +pub mod key_value; +pub mod mediawiki; +pub mod template; + +use std::env; + +/// Checks environment variable `DRY_RUN` to see if any external operations +/// should *actually* be done. +/// +/// If `is_dry_run` returns `true`, just report what you *would* do, and +/// don't actually e.g. send emails. +pub fn is_dry_run() -> bool { + env::var("DRY_RUN").map(|v| !v.is_empty()).unwrap_or(false) +} diff --git a/src/main.rs b/src/main.rs index 60c8846..ce1c9a4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,20 +43,15 @@ use std::error::Error; use std::fmt::Display; use std::io::IsTerminal; -mod key_value; -use key_value::KeyValueStore as KV; -mod config_spec; -use config_spec::{CfgField, CfgGroup, CfgSpec}; -mod template; -pub mod variables_and_settings; +use cccron_lib::config_spec::{self, CfgField, CfgGroup, CfgSpec}; +use cccron_lib::key_value::KeyValueStore as KV; +mod variables_and_settings; -mod email; -use email::{Email, SimpleEmail}; -mod hedgedoc; -use hedgedoc::HedgeDoc; -mod mediawiki; -use mediawiki::Mediawiki; -mod date; +use cccron_lib::date; +use cccron_lib::email::{self, Email, SimpleEmail}; +use cccron_lib::hedgedoc::{self, HedgeDoc}; +use cccron_lib::is_dry_run; +use cccron_lib::mediawiki::{self, Mediawiki}; const FALLBACK_TEMPLATE: &str = variables_and_settings::FALLBACK_TEMPLATE; @@ -113,15 +108,6 @@ const CONFIG_SPEC: CfgSpec<'static> = CfgSpec { /* ***** Runtime Configuration (Arguments & Environment Variables) ***** */ -/// Checks environment variable `DRY_RUN` to see if any external operations -/// should *actually* be done. -/// -/// If `is_dry_run` returns `true`, just report what you *would* do, and -/// don't actually e.g. send emails. -fn is_dry_run() -> bool { - env::var("DRY_RUN").map(|v| !v.is_empty()).unwrap_or(false) -} - /// Checks environment variable `VERBOSE` to see if status messages should be /// printed. /// diff --git a/src/template.rs b/src/template.rs index f6dfb1a..bf1d0c9 100644 --- a/src/template.rs +++ b/src/template.rs @@ -9,7 +9,7 @@ where } pub fn config_replacer<'a>( - config: &'a crate::KV, blacklist_substrings: &'a [&'a str], + config: &'a crate::key_value::KeyValueStore, blacklist_substrings: &'a [&'a str], ) -> impl Fn(&Captures) -> String + 'a { move |caps: &Captures| { let key = &caps[1];