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 * Validity.t) 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 : Wordlist.t -> Criteria.t list -> State.proposition option = fun analysis rules -> let word = Freq_analysis.analyse analysis |> Freq_analysis.pick_next_word analysis 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 -> Validity.Wellplaced | _ -> Validity.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.to_seq words |> Seq.map (fun w -> Jstr.(to_string (uppercased w))) |> Wordlist.add_words rules 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