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
- Create instance with
Productivity::new()- automatically loads all relevant data - Call
calculate_productivity()for the main productivity percentage - Use helper methods for break recommendations and analysis (now parameter-free)
Fields§
§workday: WorkdayThe 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: ProductivityConfigProductivity configuration settings and thresholds
Implementations§
Source§impl Productivity
impl Productivity
Sourcepub fn new(workday: &Workday) -> Result<Self>
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);Sourcepub fn with_test_data(
workday: &Workday,
short_pauses: Vec<Pause>,
long_pauses: Vec<Pause>,
) -> Self
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 analyzeshort_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();Sourcepub fn is_below_threshold(&self) -> bool
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.
Sourcepub fn calculate_productivity(&self) -> f64
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
- Manual Breaks: User-defined break periods (excluded from work time)
- Long Pauses: Automatic pauses >= min_pause_duration (recorded in DB)
- Short Pauses: Automatic pauses < min_pause_duration (not recorded in DB)
- 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");
}