Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save stijnmoreels/be00b39dd2d4c73ed8d9ce88014e5a8e to your computer and use it in GitHub Desktop.

Select an option

Save stijnmoreels/be00b39dd2d4c73ed8d9ce88014e5a8e to your computer and use it in GitHub Desktop.
open FPrimitive
module Folder =
/// Alphanum10 -> Folder list -> Result<Folder, ErrorsByTag>
let create id xs = result {
let! children = specResult xs {
tag "folder.width"
inclusiveBetweenOf List.length 0 Folder.Limits.maxWidth $"require a max of {Folder.Limits.maxWidth} children on each level" }
let x = { Id = id; Children = children }
return! let d = depth x in if d > Folder.Limits.maxDepth
then Spec.error "folder.depth" $"require a maximum folder depth of {Folder.Limits.maxDepth} but got {d}"
else Ok x }
module Adapter =
/// FolderDto list -> Result<Folder list, ErrorsByTag>
let toFolders xs = result {
let diffParentId =
Spec.tag "folder.id"
|> Spec.verify (fun f -> f.Id <> f.ParentId) "cannot reference oneself as parent folder"
|> Spec.list
let! xs = specResult xs {
tag "folder.id"
unique (fun x -> x.Id) "require an unique ID for each folder"
dependsOn diffParentId }
let rec withChildren depth parent children = result {
let! id = Alphanum10.create parent.Id
let! mapped =
children
|> List.filter (fun c -> c.ParentId = parent.Id)
|> List.map (fun c -> withChildren (depth + 1) c children)
|> Result.sequenceMapList
return! Folder.create id mapped }
return! xs |> List.filter (fun x -> isNull x.ParentId)
|> List.map (fun x -> withChildren 0 x xs)
|> Result.sequenceMapList }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment