Rules

Struct Rules 

Source
pub struct Rules { /* private fields */ }
Expand description

A collection of end-of-life rules for Gmail message processing.

Rules manages a set of end-of-life rule instances that define how Gmail messages should be processed based on their age and labels. Rules can move messages to trash or delete them permanently when they exceed specified retention periods.

§Structure

Each rule has:

  • A unique ID for identification
  • A retention period (age threshold)
  • Optional target labels
  • An action (trash or delete)

§Default Rules

When created with Rules::new() or Rules::default(), the following default rules are automatically added:

  • 1 year retention with auto-generated label
  • 1 week retention with auto-generated label
  • 1 month retention with auto-generated label
  • 5 year retention with auto-generated label

§Examples

use cull_gmail::{Rules, Retention, MessageAge};

let rules = Rules::new();
// Default rules are automatically created
assert!(!rules.labels().is_empty());

§Serialization

Rules can be serialized to and from TOML format for persistence.

Implementations§

Source§

impl Rules

Source

pub fn new() -> Self

Creates a new Rules instance with default retention rules.

This creates the same configuration as Rules::default(), including several pre-configured rules with common retention periods.

§Examples
use cull_gmail::Rules;

let rules = Rules::new();
// Default rules are automatically created
let labels = rules.labels();
assert!(!labels.is_empty());
Source

pub fn get_rule(&self, id: usize) -> Option<EolRule>

Retrieves a rule by its unique ID.

Returns a cloned copy of the rule if found, or None if no rule exists with the specified ID.

§Arguments
  • id - The unique identifier of the rule to retrieve
§Examples
use cull_gmail::{Rules, Retention, MessageAge};

let mut rules = Rules::new();
let retention = Retention::new(MessageAge::Days(30), false);
rules.add_rule(retention, None, false);

// Retrieve a rule (exact ID depends on existing rules)
if let Some(rule) = rules.get_rule(1) {
    println!("Found rule: {}", rule.describe());
}
Source

pub fn add_rule( &mut self, retention: Retention, label: Option<&str>, delete: bool, ) -> &mut Self

Adds a new rule to the rule set with the specified retention settings.

Creates a new rule with an automatically assigned unique ID. If a label is specified and another rule already targets that label, a warning is logged and the rule is not added.

§Arguments
  • retention - The retention configuration (age and label generation)
  • label - Optional label that this rule should target
  • delete - If true, messages are permanently deleted; if false, moved to trash
§Returns

Returns a mutable reference to self for method chaining.

§Examples
use cull_gmail::{Rules, Retention, MessageAge, EolAction};

let mut rules = Rules::new();

// Add a rule to trash newsletters after 3 months
let retention = Retention::new(MessageAge::Months(3), false);
rules.add_rule(retention, Some("newsletter"), false);

// Add a rule to delete spam after 7 days
let spam_retention = Retention::new(MessageAge::Days(7), false);
rules.add_rule(spam_retention, Some("spam"), true);
Source

pub fn labels(&self) -> Vec<String>

Returns all labels targeted by the current rules.

This method collects labels from all rules in the set and returns them as a single vector. Duplicate labels are not removed.

§Examples
use cull_gmail::{Rules, Retention, MessageAge};

let mut rules = Rules::new();
let retention = Retention::new(MessageAge::Days(30), false);
rules.add_rule(retention, Some("test-label"), false);

let labels = rules.labels();
assert!(labels.len() > 0);
println!("Configured labels: {:?}", labels);
Source

pub fn remove_rule_by_id(&mut self, id: usize) -> Result<()>

Removes a rule from the set by its unique ID.

If the rule exists, it is removed and a confirmation message is printed. If the rule doesn’t exist, the operation completes successfully without error.

§Arguments
  • id - The unique identifier of the rule to remove
§Examples
use cull_gmail::{Rules, Retention, MessageAge};

let mut rules = Rules::new();
// Assume rule ID 1 exists from defaults
rules.remove_rule_by_id(1).expect("Failed to remove rule");
§Errors

This method currently always returns Ok(()), but the return type is Result<()> for future extensibility.

Source

pub fn remove_rule_by_label(&mut self, label: &str) -> Result<()>

Removes a rule from the set by targeting one of its labels.

Finds the rule that contains the specified label and removes it. If multiple rules target the same label, only one is removed.

§Arguments
  • label - The label to search for in existing rules
§Examples
use cull_gmail::{Rules, Retention, MessageAge};

let mut rules = Rules::new();
let retention = Retention::new(MessageAge::Days(30), false);
rules.add_rule(retention, Some("newsletter"), false);

// Remove the rule targeting the newsletter label
rules.remove_rule_by_label("newsletter")
     .expect("Failed to remove rule");
§Errors
Source

pub fn get_rules_by_label_for_action( &self, action: EolAction, ) -> BTreeMap<String, EolRule>

Returns a mapping from labels to rules that target them.

Creates a BTreeMap where each key is a label and each value is a cloned copy of the rule that targets that label. If multiple rules target the same label, only one will be present in the result (the last one processed).

§Examples
use cull_gmail::{Rules, Retention, MessageAge};

let mut rules = Rules::new();
let retention = Retention::new(MessageAge::Days(30), false);
rules.add_rule(retention, Some("test"), false);

let label_map = rules.get_rules_by_label(EolAction::Trash);
if let Some(rule) = label_map.get("test") {
    println!("Rule for 'test' label: {}", rule.describe());
}
Source

pub fn add_label_to_rule(&mut self, id: usize, label: &str) -> Result<()>

Adds a label to an existing rule and saves the configuration.

Finds the rule with the specified ID and adds the given label to it. The configuration is automatically saved to disk after the change.

§Arguments
  • id - The unique identifier of the rule to modify
  • label - The label to add to the rule
§Examples
use cull_gmail::Rules;

let mut rules = Rules::load().expect("Failed to load rules");
rules.add_label_to_rule(1, "new-label")
     .expect("Failed to add label");
§Errors
  • Error::RuleNotFound if no rule exists with the specified ID
  • IO errors from saving the configuration file
Source

pub fn remove_label_from_rule(&mut self, id: usize, label: &str) -> Result<()>

Removes a label from an existing rule and saves the configuration.

Finds the rule with the specified ID and removes the given label from it. The configuration is automatically saved to disk after the change.

§Arguments
  • id - The unique identifier of the rule to modify
  • label - The label to remove from the rule
§Examples
use cull_gmail::Rules;

let mut rules = Rules::load().expect("Failed to load rules");
rules.remove_label_from_rule(1, "old-label")
     .expect("Failed to remove label");
§Errors
  • Error::RuleNotFound if no rule exists with the specified ID
  • IO errors from saving the configuration file
Source

pub fn set_action_on_rule( &mut self, id: usize, action: &EolAction, ) -> Result<()>

Sets the action for an existing rule and saves the configuration.

Finds the rule with the specified ID and updates its action (trash or delete). The configuration is automatically saved to disk after the change.

§Arguments
  • id - The unique identifier of the rule to modify
  • action - The new action to set (Trash or Delete)
§Examples
use cull_gmail::{Rules, EolAction};

let mut rules = Rules::load().expect("Failed to load rules");
rules.set_action_on_rule(1, &EolAction::Delete)
     .expect("Failed to set action");
§Errors
  • Error::RuleNotFound if no rule exists with the specified ID
  • IO errors from saving the configuration file
Source

pub fn save(&self) -> Result<()>

Saves the current rule configuration to disk.

The configuration is saved as TOML format to ~/.cull-gmail/rules.toml. The directory is created if it doesn’t exist.

§Examples
use cull_gmail::{Rules, Retention, MessageAge};

let mut rules = Rules::new();
let retention = Retention::new(MessageAge::Days(30), false);
rules.add_rule(retention, Some("test"), false);

rules.save().expect("Failed to save configuration");
§Errors
  • TOML serialization errors
  • IO errors when writing to the file system
  • File system permission errors
Source

pub fn save_to(&self, path: Option<&Path>) -> Result<()>

Saves the current rule configuration to a specified path.

If no path is provided, defaults to ~/.cull-gmail/rules.toml. The directory is created if it doesn’t exist.

§Arguments
  • path - Optional path where the rules should be saved
§Examples
use cull_gmail::Rules;
use std::path::Path;

let rules = Rules::new();
rules.save_to(Some(Path::new("/custom/path/rules.toml")))
     .expect("Failed to save");
§Errors
  • TOML serialization errors
  • IO errors when writing to the file system
  • File system permission errors
Source

pub fn load() -> Result<Rules>

Loads rule configuration from disk.

Reads the configuration from ~/.cull-gmail/rules.toml and deserializes it into a Rules instance.

§Examples
use cull_gmail::Rules;

match Rules::load() {
    Ok(rules) => {
        println!("Loaded {} rules", rules.labels().len());
        rules.list_rules().expect("Failed to list rules");
    }
    Err(e) => println!("Failed to load rules: {}", e),
}
§Errors
  • IO errors when reading from the file system
  • TOML parsing errors if the file is malformed
  • File not found errors if the configuration doesn’t exist
Source

pub fn load_from(path: Option<&Path>) -> Result<Rules>

Loads rule configuration from a specified path.

If no path is provided, defaults to ~/.cull-gmail/rules.toml.

§Arguments
  • path - Optional path to load rules from
§Examples
use cull_gmail::Rules;
use std::path::Path;

let rules = Rules::load_from(Some(Path::new("/custom/path/rules.toml")))
    .expect("Failed to load rules");
§Errors
  • IO errors when reading from the file system
  • TOML parsing errors if the file is malformed
  • File not found errors if the configuration doesn’t exist
Source

pub fn list_rules(&self) -> Result<()>

Prints all configured rules to standard output.

Each rule is printed on a separate line with its description, including the rule ID, action, and age criteria.

§Examples
use cull_gmail::Rules;

let rules = Rules::new();
rules.list_rules().expect("Failed to list rules");
// Output:
// Rule #1 is active on `retention/1-years` to move the message to trash if it is more than 1 years old.
// Rule #2 is active on `retention/1-weeks` to move the message to trash if it is more than 1 weeks old.
// ...
§Errors

This method currently always returns Ok(()), but the return type is Result<()> for consistency with other methods and future extensibility.

Trait Implementations§

Source§

impl Debug for Rules

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Rules

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for Rules

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for Rules

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl Freeze for Rules

§

impl RefUnwindSafe for Rules

§

impl Send for Rules

§

impl Sync for Rules

§

impl Unpin for Rules

§

impl UnwindSafe for Rules

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> ErasedDestructor for T
where T: 'static,