lib target; working doctests

also paves the way for further cleanups
This commit is contained in:
nobody 2024-08-20 08:38:20 +02:00 committed by murmeldin
parent 7093280d80
commit 60956b6303
7 changed files with 50 additions and 27 deletions

View file

@ -1,5 +1,5 @@
[package] [package]
name = "Plenum-Bot" name = "plenum_bot"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
@ -21,3 +21,11 @@ serde = {version = "1.0.204", features = ["derive"]}
serde_json = "1.0.122" serde_json = "1.0.122"
colored = "2.1.0" colored = "2.1.0"
nom = "7.1.3" nom = "7.1.3"
[[bin]]
name = "Plenum-Bot"
path = "src/main.rs"
[lib]
name = "cccron_lib"
path = "src/lib.rs"

View file

@ -2,6 +2,7 @@
//! //!
//! Per module that wants config fields, declare a //! Per module that wants config fields, declare a
//! ```rust //! ```rust
//! # use cccron_lib::config_spec::{CfgGroup, CfgField};
//! pub const CONFIG: CfgGroup<'static> = CfgGroup { //! pub const CONFIG: CfgGroup<'static> = CfgGroup {
//! name: "modname", // this will be the field name prefix in the KV store //! name: "modname", // this will be the field name prefix in the KV store
//! description: "what this module is for", //! 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. //! and then in the main module, glue them all together and use them to populate defaults etc.
//! //!
//! ```rust //! ```rust
//! # use cccron_lib::config_spec::{self, CfgSpec};
//! # use cccron_lib::key_value::KeyValueStore;
//! # mod modname { //! # mod modname {
//! # use cccron_lib::config_spec::{CfgGroup, CfgField};
//! # pub const CONFIG: CfgGroup<'static> = CfgGroup { //! # pub const CONFIG: CfgGroup<'static> = CfgGroup {
//! # name: "modname", // this will be the field name prefix in the KV store //! # name: "modname", // this will be the field name prefix in the KV store
//! # description: "what this module is for", //! # description: "what this module is for",
@ -35,12 +39,15 @@
//! // etc. //! // etc.
//! ], //! ],
//! }; //! };
//! # fn main() -> rusqlite::Result<()> {
//! // open a config file somewhere (we use a dummy to not cause side-effects) //! // open a config file somewhere (we use a dummy to not cause side-effects)
//! let config = KeyValueStore::new_dummy()?; //! let config = KeyValueStore::new_dummy()?;
//! // always: //! // always:
//! CONFIG_SPEC.populate_defaults(&config); //! config_spec::populate_defaults(&CONFIG_SPEC, &config);
//! // (and then defaults will be set:) //! // (and then defaults will be set:)
//! assert_eq!( config.get("modname-user").unwrap(), "xyzzy" ); //! assert_eq!( config.get("modname-user").unwrap(), "xyzzy" );
//! # Ok(())
//! # }
//! ``` //! ```
//! //!
//! ```ignore //! ```ignore

View file

@ -115,6 +115,8 @@ pub fn summarize(pad_content: String) -> String {
} }
/// For the config, make a new pad ID (by actually making a pad.) /// 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<String, Box<dyn Error>> { fn make_pad_id(
_key: &str, config: &crate::key_value::KeyValueStore, is_dry_run: bool,
) -> Result<String, Box<dyn Error>> {
HedgeDoc::new(&config.get("hedgedoc-server-url").unwrap(), is_dry_run).create_pad() HedgeDoc::new(&config.get("hedgedoc-server-url").unwrap(), is_dry_run).create_pad()
} }

View file

@ -6,6 +6,7 @@
//! ``` //! ```
//! //!
//! ``` //! ```
//! # use cccron_lib::key_value::KeyValueStore;
//! # let cfg = KeyValueStore::new_dummy()?; //! # let cfg = KeyValueStore::new_dummy()?;
//! // Ensure defaults exist. (Do this early, this function panics on error.) //! // Ensure defaults exist. (Do this early, this function panics on error.)
//! cfg.default( "foo", "bar" ); //! cfg.default( "foo", "bar" );
@ -13,11 +14,12 @@
//! // Normal use after that. //! // Normal use after that.
//! let foo = cfg.get( "foo" ).unwrap(); //! let foo = cfg.get( "foo" ).unwrap();
//! let baz = &cfg["baz"]; // shorthand that LEAKS the string and panics on error //! 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.set( "fnord", "23" )?;
//! cfg.delete( "foo" )?; //! cfg.delete( "foo" )?;
//! // If any writes failed, this flag will be set and the data got logged to stderr. //! // If any writes failed, this flag will be set and the data got logged to stderr.
//! let all_ok = !cfg.has_errors(); //! let all_ok = !cfg.has_errors();
//! # Ok::<(),rusqlite::Error>(())
//! ``` //! ```
use colored::Colorize; use colored::Colorize;

18
src/lib.rs Normal file
View file

@ -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)
}

View file

@ -43,20 +43,15 @@ use std::error::Error;
use std::fmt::Display; use std::fmt::Display;
use std::io::IsTerminal; use std::io::IsTerminal;
mod key_value; use cccron_lib::config_spec::{self, CfgField, CfgGroup, CfgSpec};
use key_value::KeyValueStore as KV; use cccron_lib::key_value::KeyValueStore as KV;
mod config_spec; mod variables_and_settings;
use config_spec::{CfgField, CfgGroup, CfgSpec};
mod template;
pub mod variables_and_settings;
mod email; use cccron_lib::date;
use email::{Email, SimpleEmail}; use cccron_lib::email::{self, Email, SimpleEmail};
mod hedgedoc; use cccron_lib::hedgedoc::{self, HedgeDoc};
use hedgedoc::HedgeDoc; use cccron_lib::is_dry_run;
mod mediawiki; use cccron_lib::mediawiki::{self, Mediawiki};
use mediawiki::Mediawiki;
mod date;
const FALLBACK_TEMPLATE: &str = variables_and_settings::FALLBACK_TEMPLATE; const FALLBACK_TEMPLATE: &str = variables_and_settings::FALLBACK_TEMPLATE;
@ -113,15 +108,6 @@ const CONFIG_SPEC: CfgSpec<'static> = CfgSpec {
/* ***** Runtime Configuration (Arguments & Environment Variables) ***** */ /* ***** 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 /// Checks environment variable `VERBOSE` to see if status messages should be
/// printed. /// printed.
/// ///

View file

@ -9,7 +9,7 @@ where
} }
pub fn config_replacer<'a>( 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 { ) -> impl Fn(&Captures) -> String + 'a {
move |caps: &Captures| { move |caps: &Captures| {
let key = &caps[1]; let key = &caps[1];