(.using [library [lux (.except) [abstract [monad (.only do)]] [control ["[0]" exception (.only exception:)] ["<>" parser ["<[0]>" json (.only Parser)]]] [data [text ["%" \\format (.only format)]]] [math [number ["n" nat] ["i" int] ["f" frac]]]]] ["[0]" // ["[1]" license (.only Identification Termination Liability Distribution Commercial Extension Entity Black_List URL Attribution Addendum License) ["[0]" time (.only Period)] ["[0]" copyright]]]) (def identification (Parser Identification) (.object (all <>.and (.field "name" .string) (.field "version" .string)))) (exception: .public (cannot_use_fractional_amount [amount Frac]) (exception.report "Amount" (%.frac amount))) (exception: .public (cannot_use_negative_amount [amount Int]) (exception.report "Amount" (%.int amount))) (def amount (Parser Nat) (do <>.monad [amountF .number #let [amountI (f.int amountF)] _ (<>.assert (exception.construct ..cannot_use_fractional_amount [amountF]) (f.= amountF (i.frac amountI))) _ (<>.assert (exception.construct ..cannot_use_negative_amount [amountI]) (i.> +0 amountI))] (wrap (.nat amountI)))) (exception: .public (invalid_period [period (Period Nat)]) (exception.report "Start" (%.nat (the time.#start period)) "End" (%.nat (the time.#end period)))) (def period (Parser (Period Nat)) (.object (do <>.monad [start (.field "start" ..amount) end (.field "end" ..amount) #let [period [time.#start start time.#end end]] _ (<>.assert (exception.construct ..invalid_period [period]) (n.<= end start))] (wrap period)))) (def copyright_holder (Parser copyright.Holder) (.object (all <>.and (.field "name" .string) (.field "period" ..period)))) (def termination (Parser Termination) (.object (all <>.and (.field "patent retaliation?" .boolean) (.field "termination period" ..amount) (.field "grace period" ..amount)))) (def liability (Parser Liability) (.object (all <>.and (.field "can accept?" .boolean) (.field "disclaim high risk?" .boolean)))) (def distribution (Parser Distribution) (.object (all <>.and (.field "can re-license?" .boolean) (.field "can multi-license?" .boolean)))) (def commercial (Parser Commercial) (.object (all <>.and (.field "can sell?" .boolean) (.field "require contributor credit?" .boolean) (.field "allow contributor endorsement?" .boolean)))) (def extension (Parser Extension) (.object (all <>.and (.field "same license?" .boolean) (.field "must be distinguishable?" .boolean) (.field "notification period" (.nullable ..period)) (.field "must describe modifications?" .boolean)))) (def entity (Parser Entity) .string) (def black_list (Parser Black_List) (.object (all <>.and (.field "justification" (.nullable .string)) (.field "entities" (.array (<>.many ..entity)))))) (def url (Parser URL) .string) (def attribution (Parser Attribution) (.object (all <>.and (.field "copyright-notice" .string) (.field "phrase" (.nullable .string)) (.field "url" ..url) (.field "image" (.nullable ..url))))) (def addendum (Parser Addendum) (.object (all <>.and (.field "commons clause?" .boolean) ))) (def .public license (Parser License) (.object (all <>.and (.field "copyright-holders" (.array (<>.many ..copyright_holder))) (.field "identification" (.nullable ..identification)) (.field "termination" ..termination) (.field "liability" ..liability) (.field "distribution" ..distribution) (.field "commercial" ..commercial) (.field "extension" ..extension) (.field "black-lists" (.array (<>.some ..black_list))) (.field "attribution" (.nullable ..attribution)) (<>.default [//.#commons_clause? false] (.field "addendum" ..addendum)) )))