... This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. ... If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. (.require [library [lux (.except for) [abstract [equivalence (.only Equivalence)] [monoid (.only Monoid)] [monad (.only do)]] [control ["<>" parser] ["[0]" maybe (.use "[1]#[0]" functor)] ["[0]" exception]] [data ["[0]" text (.use "[1]#[0]" equivalence) ["%" \\format] ["<[1]>" \\parser (.only Parser)]] [collection ["[0]" list (.use "[1]#[0]" functor mix) ["/" property]]]] [math [number (.only hex)]] ["[0]" meta (.only) ["[0]" code (.only) ["<[1]>" \\parser]] [macro [syntax (.only syntax)]]]]]) (type .public Configuration (/.List Text)) (def .public equivalence (Equivalence Configuration) (/.equivalence text.equivalence)) (def .public monoid (Monoid Configuration) /.monoid) (def .public empty Configuration /.empty) (with_template [ ] [(def Text (text.of_char (hex )))] ["02" start] ["03" end] ) (def format' (-> Text Text) (text.enclosed [..start ..end])) (def .public format (%.Format Configuration) (|>> (list#each (function (_ [feature value]) (%.format (..format' feature) (..format' value)))) text.together)) (def .public parser (Parser Configuration) (let [parser' (is (Parser Text) (<| (<>.after (.this ..start)) (<>.before (.this ..end)) (.slice (.some! (.none_of! ..end)))))] (<>.some (<>.and parser' parser')))) (exception.def .public invalid) (def configuration (.Parser Configuration) (.tuple (<>.some (<>.and .text .text)))) (def (subsumes? actual expected) (-> Configuration Configuration Bit) (when expected {.#End} true {.#Item [feature value] tail} (and (|> actual (/.value feature) (maybe#each (text#= value)) (maybe.else false)) (subsumes? expected tail)))) (def .public for (syntax (_ [specializations (<>.some (<>.and ..configuration .any)) default (<>.maybe .any)]) (do meta.monad [actual meta.configuration] (when (list#mix (function (_ [expected then] choice) (if (subsumes? actual expected) {.#Some then} choice)) default specializations) {.#Some it} (in (list it)) {.#None} (meta.failure (exception.error ..invalid []))))))