How To Model A Validated Wrapper
Use this pattern when the wire value is simple but the in-memory model should enforce a smart-constructor rule.
open CodecMapper.Schema
type UserId = UserId of int
module UserId =
let create value =
if value > 0 then Ok(UserId value)
else Error "UserId must be positive"
let value (UserId value) = value
type Account = { Id: UserId; Name: string }
let makeAccount id name = { Id = id; Name = name }
let userIdSchema =
int
|> tryMap UserId.create UserId.value
let accountSchema =
define<Account>
|> construct makeAccount
|> fieldWith "id" _.Id userIdSchema
|> field "name" _.Name
|> build
Extract the tryMap pipeline into a named schema when the same wrapper rule appears across multiple contracts.
Multiple items
union case UserId.UserId: int -> UserId
--------------------
type UserId = | UserId of int
union case UserId.UserId: int -> UserId
--------------------
type UserId = | UserId of int
type UserId = | UserId of int
Multiple items
val int: value: 'T -> int (requires member op_Explicit)
--------------------
type int = int32
--------------------
type int<'Measure> = int
val int: value: 'T -> int (requires member op_Explicit)
--------------------
type int = int32
--------------------
type int<'Measure> = int
val create: value: int -> Result<UserId,string>
val value: int
union case Result.Ok: ResultValue: 'T -> Result<'T,'TError>
union case Result.Error: ErrorValue: 'TError -> Result<'T,'TError>
val value: UserId -> int
type Account =
{
Id: UserId
Name: string
}
Multiple items
union case UserId.UserId: int -> UserId
--------------------
module UserId from HOWTOMODELAVALIDATEDWRAPPER
--------------------
type UserId = | UserId of int
union case UserId.UserId: int -> UserId
--------------------
module UserId from HOWTOMODELAVALIDATEDWRAPPER
--------------------
type UserId = | UserId of int
Multiple items
val string: value: 'T -> string
--------------------
type string = System.String
val string: value: 'T -> string
--------------------
type string = System.String
val makeAccount: id: UserId -> name: string -> Account
val id: UserId
val name: string
val userIdSchema: obj
val accountSchema: obj
CodecMapper