-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathDSL.fs
68 lines (51 loc) · 2.22 KB
/
DSL.fs
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
module SharpPoint.DSL
open SharpPoint.Domain
(* --- Slide --- *)
[<RequireQualifiedAccess>]
type SlideProperty =
| Header of header: string
| Content of content: SlideContent
type SlideBuilder() =
member inline _.Yield(()) = ()
member inline x.Run(props: SlideProperty list) =
props
|> List.fold
(fun slide prop ->
match prop with
| SlideProperty.Header header -> { slide with Header = header }
| SlideProperty.Content content -> { slide with Content = content :: slide.Content })
{ Header = ""; Content = [] }
[<CustomOperation("header")>]
member inline _.Header((), header: string) = [ SlideProperty.Header header ]
[<CustomOperation("text")>]
member inline _.Text(prev: SlideProperty list, text: string) =
(Text text |> SlideProperty.Content) :: prev
[<CustomOperation("image")>]
member inline _.Image(prev: SlideProperty list, url: string) =
(Image url |> SlideProperty.Content) :: prev
let slide = SlideBuilder()
[<RequireQualifiedAccess>]
type DeckProperty =
| Title of string
| Slide of Slide
(* --- Deck --- *)
type DeckBuilder() =
member inline _.Yield(()) = ()
member inline _.Yield(slide: Slide) = DeckProperty.Slide slide
member inline _.Delay(f: unit -> DeckProperty list) = f ()
member inline _.Delay(f: unit -> DeckProperty) = [ f () ]
member inline _.Combine(newProp: DeckProperty, previousProps: DeckProperty list) = newProp :: previousProps
member inline x.For(prop: DeckProperty, f: unit -> DeckProperty list) = x.Combine(prop, f ())
member inline x.For(prop: DeckProperty, f: unit -> DeckProperty) = [prop; f()]
member inline x.Run(props: DeckProperty list) =
props
|> List.fold
(fun deck prop ->
match prop with
| DeckProperty.Title title -> { deck with Title = title }
| DeckProperty.Slide slide -> { deck with Slides = deck.Slides @ [ slide ] })
{ Title = ""; Slides = [] }
member inline x.Run(prop: DeckProperty) = x.Run([ prop ])
[<CustomOperation("title")>]
member inline _.Title((), title: string) = DeckProperty.Title title
let deck = DeckBuilder()