open Import

type t =
  | Byte
  | Native
  | Best (** [Native] if available and [Byte] if not *)

val decode : t Decoder.t
val compare : t -> t -> Ordering.t
val to_dyn : t -> Dyn.t
val encode : t Encoder.t

module Kind : sig
  type t =
    | Inherited
    | Requested of Loc.t
end

module Map : sig
  type nonrec 'a t =
    { byte : 'a
    ; native : 'a
    ; best : 'a
    }
end

module Set : sig
  type nonrec t = Kind.t option Map.t

  val decode : t Decoder.t
end

module Lib : sig
  type mode_conf := t

  type t =
    | Ocaml of mode_conf
    | Melange

  val to_dyn : t -> Dyn.t

  module Map : sig
    type nonrec 'a t =
      { ocaml : 'a Map.t
      ; melange : 'a
      }
  end

  module Set : sig
    type mode_conf := t
    type nonrec t = Kind.t option Map.t

    val of_list : (mode_conf * Kind.t) list -> t
    val decode : t Decoder.t
    val default : Loc.t -> t
    val eval : t -> has_native:bool -> Lib_mode.Map.Set.t
    val decode_osl : stanza_loc:Loc.t -> Dune_project.t -> t Decoder.t
  end
end
