open StdLabels open Note open Motus_lib open Brr type t = { length : int ; content : (int * Jstr.t, Jv.Error.t) result ; sender : (int * Jstr.t * State.letter_validity) E.send ; proposition : State.proposition } (** Pick the next word from the dictionnary, and return it as a proposition. If the word is empty (no word) return [None], else return a proposition which can be edited by the user. The rule list is used to identify the letter already fixed by the previous results. *) let get_proposition : Persistence.t -> Criteria.t list -> State.proposition option = fun analysis rules -> let word = Persistence.extract_freq analysis |> Persistence.pick_next_word analysis |> fst in match String.equal String.empty word with | true -> None | false -> let i = ref 0 in let proposition = word |> String.to_seq |> Seq.map (fun c -> let wellplaced = List.exists rules ~f:(function | Motus_lib.Criteria.Contain (_, Some i') when !i = i' -> true | _ -> false ) in incr i; let validity = match wellplaced with | true -> State.Wellplaced | _ -> State.Missing in Some (Jstr.of_char c, validity) ) |> List.of_seq in Some proposition let process { sender; length; content; proposition } state = match content with | Ok (200, value) -> let rules = Criteria.Lenght length :: State.get_current_rules proposition in let words = Jstr.cuts ~sep:(Jstr.v "\n") value in let analysis = List.fold_left ~f:(fun a w -> let upper = Jstr.uppercased w in Persistence.add_word rules a (Jstr.to_string upper) ) ~init:(Persistence.empty_data ()) words in let current_prop = get_proposition analysis rules and fields = FieldList.make length sender in ( match current_prop with | None -> state | Some prop -> FieldList.set_with_props prop fields rules; State. { analysis ; rules ; length ; current_prop = prop ; propositions = [] ; fields } ) | _ -> Console.(log [ Jstr.v "No words found" ]); state