Skip to main content

Si

Struct Si 

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

SiServer client. Authentication is two-stage: LDAP login yields a token, the token is exchanged for a PORTALSESSID cookie, and the cookie rides on every API call.

Implementations§

Source§

impl Si

Source

pub fn new(config: &SiConfig) -> Self

Builds a client from the config; no network activity yet.

use kasl::api::si::{Si, SiConfig};

let config = SiConfig {
    login: "username".to_string(),
    auth_url: "https://auth.company.com".to_string(),
    api_url: "https://api.company.com".to_string(),
};
let si = Si::new(&config);
Source

pub async fn send(&mut self, data: &str, date: &NaiveDate) -> Result<StatusCode>

Submits the daily report (tasks as JSON) for the date. On a 401 the cached session is dropped and the call retried up to the limit; a network error maps to BAD_REQUEST so a scheduled send fails soft.

let mut si = Si::new(&config);
let report_data = r#"{"hours": 8, "tasks": 5}"#.to_string();
let today = Local::now().date_naive();

let status = si.send(&report_data, &today).await?;
if status.is_success() {
    println!("Report submitted successfully");
}
Source

pub async fn send_monthly(&mut self, date: &NaiveDate) -> Result<StatusCode>

Submits the monthly report for the month containing date, with the same 401-retry and network-error behavior as Si::send.

let mut si = Si::new(&config);
let today = Local::now().date_naive();

if si.is_last_working_day_of_month(&today)? {
    let status = si.send_monthly(&today).await?;
    if status.is_success() {
        println!("Monthly report submitted");
    }
}
Source

pub async fn rest_dates( &mut self, year: NaiveDate, ) -> Result<HashSet<NaiveDate>>

Fetches the company rest-date calendar for the year of date.

Every failure path - session, network, parsing - logs and returns an empty set: the calendar makes reports nicer, and its absence must not break them.

let mut si = Si::new(&config);
let this_year = Local::now().date_naive();

let rest_dates = si.rest_dates(this_year).await?;
println!("Found {} rest dates this year", rest_dates.len());

let today = Local::now().date_naive();
if rest_dates.contains(&today) {
    println!("Today is a company rest day");
}
Source

pub fn is_last_working_day_of_month(&self, date: &NaiveDate) -> Result<bool>

True when date is the month’s last working day (weekends walked back; company holidays are not consulted).

let si = Si::new(&config);
let date = NaiveDate::from_ymd_opt(2024, 1, 31).unwrap(); // January 31st

if si.is_last_working_day_of_month(&date)? {
    println!("Time to submit monthly report!");
}

Trait Implementations§

Source§

impl Debug for Si

Source§

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

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

impl Session for Si

Source§

async fn login(&self) -> Result<String>

Runs the two-stage login and returns the session id extracted from the Set-Cookie header.

Source§

fn set_credentials(&mut self, password: &str) -> Result<()>

Stores the credentials, double-base64-encoding the password as SiServer requires.

Source§

fn session_id_file(&self) -> &str

Per-provider session cache filename.
Source§

fn secret(&self) -> Secret

Per-provider secret manager (prompt text, cache file).
Source§

fn retry(&self) -> i32

Current failed-attempt count.
Source§

fn inc_retry(&mut self)

Bumps the failed-attempt count.
Source§

fn reset_retry(&mut self)

Clears the failed-attempt count after a successful login.
Source§

async fn get_session_id(&mut self) -> Result<String>

Returns a session id: cached if available, otherwise via login with up to [MAX_RETRY_COUNT] password attempts (a retry always re-prompts rather than reusing a password that just failed).
Source§

fn read_session_id(file_name: &str) -> Result<String>

Reads the cached session id.
Source§

fn write_session_id(file_name: &str, session_id: &str) -> Result<()>

Writes the session id to the cache file.
Source§

fn delete_session_id(&self) -> Result<()>

Drops the cached session, forcing a fresh login next time.

Auto Trait Implementations§

§

impl !RefUnwindSafe for Si

§

impl !UnwindSafe for Si

§

impl Freeze for Si

§

impl Send for Si

§

impl Sync for Si

§

impl Unpin for Si

§

impl UnsafeUnpin for Si

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> 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> 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 = !

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