package guardian
Source file caqti_encoders.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52(** Helper functions for creating Caqti types with custom encoder/decoders. *) module Data = struct type _ t = | [] : unit t | ( :: ) : ('a * 'b t) -> ('a * 'b) t let rec make_value : type a. a t -> a = fun xs -> match xs with | [] -> () | x :: xs -> x, make_value xs ;; end module Schema = struct type _ t = | [] : unit t | ( :: ) : ('a Caqti_type.t * 'b t) -> ('a * 'b) t let rec make_type : type a. a t -> a Caqti_type.t = fun xs -> match xs with | [] -> failwith "Schema shouldn't be empty" | x :: [] -> Caqti_type.(t2 x unit) | x :: xs -> Caqti_type.(t2 x (make_type xs)) ;; end let custom : type a b. encode:(b -> (a Data.t, string) result) -> decode:(a -> (b, string) result) -> a Schema.t -> b Caqti_type.t = fun ~encode ~decode schema -> let typ = Schema.make_type schema in let encode data = encode data |> Result.map Data.make_value in Caqti_type.custom ~encode ~decode typ ;; let custom_ok : type a b. encode:(b -> a Data.t) -> decode:(a -> b) -> a Schema.t -> b Caqti_type.t = let open CCFun in fun ~encode ~decode schema -> let typ = Schema.make_type schema in let encode = CCResult.(encode %> return %> map Data.make_value) in Caqti_type.custom ~encode ~decode:(decode %> CCResult.return) typ ;;