mirror of
https://github.com/timothymiller/cloudflare-ddns.git
synced 2026-06-20 20:35:38 -03:00
Switch reqwest to rustls-no-provider and add rustls crate; install rustls provider at startup. Replace regex::Regex with regex_lite::Regex across code. Consolidate api_get/post/put/delete into a single api_request that takes a Method and optional body. Add .dockerignore and UPX compression in Dockerfile. Remove unused domain/IDNA code, trim dead helpers, tweak tokio flavor and release opt-level, and update tests to use crate::test_client()
236 lines
6.1 KiB
Rust
236 lines
6.1 KiB
Rust
// Verbosity levels
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
|
pub enum Verbosity {
|
|
Quiet,
|
|
Notice,
|
|
Info,
|
|
Verbose,
|
|
}
|
|
|
|
// Emoji constants
|
|
pub const EMOJI_WARNING: &str = "\u{26A0}\u{FE0F}";
|
|
pub const EMOJI_ERROR: &str = "\u{274C}";
|
|
pub const EMOJI_LAUNCH: &str = "\u{1F680}";
|
|
pub const EMOJI_STOP: &str = "\u{1F6D1}";
|
|
pub const EMOJI_SLEEP: &str = "\u{1F634}";
|
|
pub const EMOJI_DETECT: &str = "\u{1F50D}";
|
|
pub const EMOJI_UPDATE: &str = "\u{2B06}\u{FE0F}";
|
|
pub const EMOJI_CREATE: &str = "\u{2795}";
|
|
pub const EMOJI_DELETE: &str = "\u{2796}";
|
|
pub const EMOJI_SKIP: &str = "\u{23ED}\u{FE0F}";
|
|
pub const EMOJI_NOTIFY: &str = "\u{1F514}";
|
|
pub const EMOJI_HEARTBEAT: &str = "\u{1F493}";
|
|
pub const EMOJI_CONFIG: &str = "\u{2699}\u{FE0F}";
|
|
|
|
const INDENT_PREFIX: &str = " ";
|
|
|
|
pub struct PP {
|
|
pub verbosity: Verbosity,
|
|
pub emoji: bool,
|
|
indent: usize,
|
|
}
|
|
|
|
impl PP {
|
|
pub fn new(emoji: bool, quiet: bool) -> Self {
|
|
Self {
|
|
verbosity: if quiet { Verbosity::Quiet } else { Verbosity::Verbose },
|
|
emoji,
|
|
indent: 0,
|
|
}
|
|
}
|
|
|
|
pub fn default_pp() -> Self {
|
|
Self::new(false, false)
|
|
}
|
|
|
|
pub fn is_showing(&self, level: Verbosity) -> bool {
|
|
self.verbosity >= level
|
|
}
|
|
|
|
pub fn indent(&self) -> PP {
|
|
PP {
|
|
verbosity: self.verbosity,
|
|
emoji: self.emoji,
|
|
indent: self.indent + 1,
|
|
}
|
|
}
|
|
|
|
fn output(&self, emoji: &str, msg: &str) {
|
|
let prefix = INDENT_PREFIX.repeat(self.indent);
|
|
if self.emoji && !emoji.is_empty() {
|
|
println!("{prefix}{emoji} {msg}");
|
|
} else {
|
|
println!("{prefix}{msg}");
|
|
}
|
|
}
|
|
|
|
fn output_err(&self, emoji: &str, msg: &str) {
|
|
let prefix = INDENT_PREFIX.repeat(self.indent);
|
|
if self.emoji && !emoji.is_empty() {
|
|
eprintln!("{prefix}{emoji} {msg}");
|
|
} else {
|
|
eprintln!("{prefix}{msg}");
|
|
}
|
|
}
|
|
|
|
pub fn infof(&self, emoji: &str, msg: &str) {
|
|
if self.is_showing(Verbosity::Info) {
|
|
self.output(emoji, msg);
|
|
}
|
|
}
|
|
|
|
pub fn noticef(&self, emoji: &str, msg: &str) {
|
|
if self.is_showing(Verbosity::Notice) {
|
|
self.output(emoji, msg);
|
|
}
|
|
}
|
|
|
|
pub fn warningf(&self, emoji: &str, msg: &str) {
|
|
self.output_err(emoji, msg);
|
|
}
|
|
|
|
pub fn errorf(&self, emoji: &str, msg: &str) {
|
|
self.output_err(emoji, msg);
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn new_with_emoji_true() {
|
|
let pp = PP::new(true, false);
|
|
assert!(pp.emoji);
|
|
}
|
|
|
|
#[test]
|
|
fn new_with_emoji_false() {
|
|
let pp = PP::new(false, false);
|
|
assert!(!pp.emoji);
|
|
}
|
|
|
|
#[test]
|
|
fn new_quiet_true_sets_verbosity_quiet() {
|
|
let pp = PP::new(false, true);
|
|
assert_eq!(pp.verbosity, Verbosity::Quiet);
|
|
}
|
|
|
|
#[test]
|
|
fn new_quiet_false_sets_verbosity_verbose() {
|
|
let pp = PP::new(false, false);
|
|
assert_eq!(pp.verbosity, Verbosity::Verbose);
|
|
}
|
|
|
|
#[test]
|
|
fn quiet_shows_only_quiet_level() {
|
|
let pp = PP::new(false, true);
|
|
assert!(pp.is_showing(Verbosity::Quiet));
|
|
assert!(!pp.is_showing(Verbosity::Notice));
|
|
assert!(!pp.is_showing(Verbosity::Info));
|
|
assert!(!pp.is_showing(Verbosity::Verbose));
|
|
}
|
|
|
|
#[test]
|
|
fn verbose_shows_all_levels() {
|
|
let pp = PP::new(false, false);
|
|
assert!(pp.is_showing(Verbosity::Quiet));
|
|
assert!(pp.is_showing(Verbosity::Notice));
|
|
assert!(pp.is_showing(Verbosity::Info));
|
|
assert!(pp.is_showing(Verbosity::Verbose));
|
|
}
|
|
|
|
#[test]
|
|
fn notice_level_shows_quiet_and_notice_only() {
|
|
let mut pp = PP::new(false, false);
|
|
pp.verbosity = Verbosity::Notice;
|
|
assert!(pp.is_showing(Verbosity::Quiet));
|
|
assert!(pp.is_showing(Verbosity::Notice));
|
|
assert!(!pp.is_showing(Verbosity::Info));
|
|
assert!(!pp.is_showing(Verbosity::Verbose));
|
|
}
|
|
|
|
#[test]
|
|
fn info_level_shows_up_to_info() {
|
|
let mut pp = PP::new(false, false);
|
|
pp.verbosity = Verbosity::Info;
|
|
assert!(pp.is_showing(Verbosity::Quiet));
|
|
assert!(pp.is_showing(Verbosity::Notice));
|
|
assert!(pp.is_showing(Verbosity::Info));
|
|
assert!(!pp.is_showing(Verbosity::Verbose));
|
|
}
|
|
|
|
#[test]
|
|
fn indent_increments_indent_level() {
|
|
let pp = PP::new(true, false);
|
|
assert_eq!(pp.indent, 0);
|
|
let child = pp.indent();
|
|
assert_eq!(child.indent, 1);
|
|
let grandchild = child.indent();
|
|
assert_eq!(grandchild.indent, 2);
|
|
}
|
|
|
|
#[test]
|
|
fn indent_preserves_verbosity_and_emoji() {
|
|
let pp = PP::new(true, true);
|
|
let child = pp.indent();
|
|
assert_eq!(child.verbosity, pp.verbosity);
|
|
assert_eq!(child.emoji, pp.emoji);
|
|
}
|
|
|
|
#[test]
|
|
fn infof_does_not_panic_when_verbose() {
|
|
let pp = PP::new(false, false);
|
|
pp.infof("", "test info message");
|
|
}
|
|
|
|
#[test]
|
|
fn infof_does_not_panic_when_quiet() {
|
|
let pp = PP::new(false, true);
|
|
pp.infof("", "test info message");
|
|
}
|
|
|
|
#[test]
|
|
fn noticef_does_not_panic_when_verbose() {
|
|
let pp = PP::new(true, false);
|
|
pp.noticef(EMOJI_DETECT, "test notice message");
|
|
}
|
|
|
|
#[test]
|
|
fn noticef_does_not_panic_when_quiet() {
|
|
let pp = PP::new(false, true);
|
|
pp.noticef("", "test notice message");
|
|
}
|
|
|
|
#[test]
|
|
fn warningf_does_not_panic() {
|
|
let pp = PP::new(true, false);
|
|
pp.warningf(EMOJI_WARNING, "test warning");
|
|
}
|
|
|
|
#[test]
|
|
fn warningf_does_not_panic_when_quiet() {
|
|
let pp = PP::new(false, true);
|
|
pp.warningf("", "test warning");
|
|
}
|
|
|
|
#[test]
|
|
fn errorf_does_not_panic() {
|
|
let pp = PP::new(true, false);
|
|
pp.errorf(EMOJI_ERROR, "test error");
|
|
}
|
|
|
|
#[test]
|
|
fn errorf_does_not_panic_when_quiet() {
|
|
let pp = PP::new(false, true);
|
|
pp.errorf("", "test error");
|
|
}
|
|
|
|
#[test]
|
|
fn default_pp_is_verbose_no_emoji() {
|
|
let pp = PP::default_pp();
|
|
assert!(!pp.emoji);
|
|
assert_eq!(pp.verbosity, Verbosity::Verbose);
|
|
}
|
|
}
|