Skip to main content

Productivity

Struct Productivity 

Source
pub struct Productivity {
    pub workday: Workday,
    pub short_pauses: Vec<Pause>,
    pub long_pauses: Vec<Pause>,
    pub config: ProductivityConfig,
}
Expand description

Productivity calculator with comprehensive work time analysis.

This structure holds all the data needed for accurate productivity calculations, including workday timing, manual breaks, different categories of pauses, and configuration settings. It provides the central calculation logic used throughout the application.

§Data Categories

  • Workday: Start/end times defining the total work session
  • Breaks: Manual breaks explicitly added by the user
  • Short Pauses: Automatic pauses below the minimum threshold (not stored in DB)
  • Long Pauses: Automatic pauses above the minimum threshold (stored in DB)
  • Config: Productivity configuration settings and thresholds

§Usage Pattern

  1. Create instance with Productivity::new() - automatically loads all relevant data
  2. Call calculate_productivity() for the main productivity percentage
  3. Use helper methods for break recommendations and analysis (now parameter-free)

Fields§

§workday: Workday

The workday record containing start/end times

§short_pauses: Vec<Pause>

Short automatic pauses (< min_pause_duration, not in database)

§long_pauses: Vec<Pause>

Long pauses (>= min_pause_duration, plus any manual protected pauses)

§config: ProductivityConfig

Productivity configuration settings and thresholds

Implementations§

Source§

impl Productivity

Source

pub fn new(workday: &Workday) -> Result<Self>

Creates a new productivity calculator for the given workday.

This constructor automatically loads all relevant data for productivity calculations:

  • Reads the current configuration to get pause duration thresholds
  • Loads manual breaks from the database for the workday date
  • Loads short pauses (below min_pause_duration threshold)
  • Loads long pauses (at or above min_pause_duration threshold)

The pause categorization is based on the min_pause_duration setting from the monitor configuration. This threshold determines which pauses are stored in the database vs. calculated on-the-fly.

§Arguments
  • workday - The workday record to analyze
§Returns

Returns a configured Productivity instance with all data loaded.

§Errors

Returns an error if:

  • Configuration file cannot be read
  • Database queries fail
  • Data integrity issues are encountered
§Examples
use kasl::libs::productivity::Productivity;
use kasl::db::workdays::Workdays;
use chrono::Local;

let mut workdays = Workdays::new()?;
let workday = workdays.fetch(Local::now().date_naive())?.unwrap();
let productivity = Productivity::new(&workday)?;
let current_productivity = productivity.calculate_productivity();
println!("Current productivity: {:.1}%", current_productivity);
Source

pub fn with_test_data( workday: &Workday, short_pauses: Vec<Pause>, long_pauses: Vec<Pause>, ) -> Self

Creates a productivity calculator with provided test data.

This constructor is primarily intended for testing scenarios where you want to provide specific pause and break data without database dependencies. It uses default productivity configuration settings.

§Arguments
  • workday - The workday record to analyze
  • short_pauses - Short automatic pauses (< threshold)
  • long_pauses - Long automatic pauses (>= threshold)
§Examples
use kasl::libs::productivity::Productivity;
use kasl::db::workdays::Workday;
use chrono::Local;

let workday = Workday {
    id: 1,
    date: Local::now().date_naive(),
    start: Local::now().naive_local(),
    end: None,
};
let productivity = Productivity::with_test_data(
    &workday,
    vec![],
    vec![]
);
let result = productivity.calculate_productivity();
Source

pub fn is_below_threshold(&self) -> bool

Reports whether productivity has fallen below the configured threshold.

The check is suppressed early in the day: a short elapsed period makes the ratio swing wildly on a single pause, so warning then would be noise. Once min_workday_fraction_before_suggest of the expected workday has passed, the figure is stable enough to act on.

§Returns

true when enough of the day has elapsed and productivity is under min_productivity_threshold.

Source

pub fn calculate_productivity(&self) -> f64

Calculates productivity percentage for the workday.

This is the central productivity calculation method that properly handles different types of work interruptions to provide accurate productivity metrics. The method implements a sophisticated calculation that distinguishes between various types of time allocation.

§Calculation Logic

The productivity calculation follows this formula:

Productivity = (Net Work Time / Available Work Time) * 100

Where:
- Gross Duration = End Time - Start Time
- Available Work Time = Gross Duration - Manual Breaks - Long Pauses  
- Net Work Time = Available Work Time - Short Pauses (adjusted for overlaps)
§Time Categories
  1. Manual Breaks: User-defined break periods (excluded from work time)
  2. Long Pauses: Automatic pauses >= min_pause_duration (recorded in DB)
  3. Short Pauses: Automatic pauses < min_pause_duration (not recorded in DB)
  4. Active Work: Time when user is actively working
§Overlap Handling

Short pauses are adjusted to avoid double-counting time that’s already accounted for in manual breaks:

  • If short_pause_duration <= break_duration: Set short pauses to zero
  • Otherwise: Subtract break duration from short pauses
§Edge Cases
  • Returns 0.0% if no available work time exists
  • Clamps result between 0.0% and 100.0% to handle calculation edge cases
  • Handles ongoing workdays by using current time as end time
§Returns

Productivity percentage as a float between 0.0 and 100.0.

§Examples
use kasl::libs::productivity::Productivity;
use kasl::db::workdays::Workday;
use chrono::Local;

let workday = Workday {
    id: 1,
    date: Local::now().date_naive(),
    start: Local::now().naive_local(),
    end: None,
};
let productivity_instance = Productivity::with_test_data(&workday, vec![], vec![]);
let productivity = productivity_instance.calculate_productivity();

if productivity >= 75.0 {
    println!("Good productivity: {:.1}%", productivity);
} else {
    println!("Consider taking a break to improve focus");
}

Auto Trait Implementations§

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

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