(.using [library [lux "*" [abstract [monad {"+" do}]] [control ["[0]" exception {"+" exception:}] ["<>" parser ["<[0]>" json {"+" Parser}]]] [data [text ["%" format {"+" format}]]] [math [number ["n" nat] ["i" int] ["f" frac]]]]] ["[0]" // "_" ["[1]" license {"+" Identification Termination Liability Distribution Commercial Extension Entity Black_List URL Attribution Addendum License} ["[0]" time {"+" Period}] ["[0]" copyright]]]) (def: identification (Parser Identification) (.object ($_ <>.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 ($_ <>.and (.field "name" .string) (.field "period" ..period)))) (def: termination (Parser Termination) (.object ($_ <>.and (.field "patent retaliation?" .boolean) (.field "termination period" ..amount) (.field "grace period" ..amount)))) (def: liability (Parser Liability) (.object ($_ <>.and (.field "can accept?" .boolean) (.field "disclaim high risk?" .boolean)))) (def: distribution (Parser Distribution) (.object ($_ <>.and (.field "can re-license?" .boolean) (.field "can multi-license?" .boolean)))) (def: commercial (Parser Commercial) (.object ($_ <>.and (.field "can sell?" .boolean) (.field "require contributor credit?" .boolean) (.field "allow contributor endorsement?" .boolean)))) (def: extension (Parser Extension) (.object ($_ <>.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 ($_ <>.and (.field "justification" (.nullable .string)) (.field "entities" (.array (<>.many ..entity)))))) (def: url (Parser URL) .string) (def: attribution (Parser Attribution) (.object ($_ <>.and (.field "copyright-notice" .string) (.field "phrase" (.nullable .string)) (.field "url" ..url) (.field "image" (.nullable ..url))))) (def: addendum (Parser Addendum) (.object ($_ <>.and (.field "commons clause?" .boolean) ))) (def: .public license (Parser License) (.object ($_ <>.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)) )))