Source

screentime-monitor / rule.ml

Full commit
open Core.Std

module T = struct
  type t =
    { days       : Day_of_week.t list
    ; categories : Category.t Blang.t
    ; limit      : Time.Span.t
    ; name       : string
    }
  with sexp, bin_io, compare, fields
end
include Sexpable.To_stringable(T)
include T

let check t daylogs =
  let relevant_span =
    let days = Day_of_week.Set.of_list t.days in
    List.fold daylogs ~init:Time.Span.zero ~f:(fun acc (date,daylog) ->
      if not (Set.mem days (Date.day_of_week date)) then acc
      else
        Map.fold (Daylog.Closed.span_map daylog) ~init:acc
          ~f:(fun ~key:cat ~data:span acc ->
            let matches =
              Blang.eval t.categories (fun cat' -> Category.(=) cat' cat)
            in
            if not matches then acc
            else Time.Span.(+) acc span))
  in
  let excess = Time.Span.(relevant_span - t.limit) in
  if Time.Span.(excess > Time.Span.zero) then `Exceeded excess else `Ok


include Comparable.Make_binable(T)