-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.fs
172 lines (146 loc) · 4.94 KB
/
Program.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
module CmdMvu.SpectreFSharp.Host
open Spectre.Console.FSharp
type OrgNr = OrgNr of string
module OrgNr =
let value (OrgNr value) = value
type SearchCompanyResult = { Name: string; OrgNr: OrgNr }
type SearchCompanyResults =
{ SearchTerm: string
SearchResult: SearchCompanyResult seq }
type Model =
| StartScreen
| SearchCompany
| NoCompanyFound of string
| SearchCompanyResult of SearchCompanyResults
| CompanyDetails of SearchCompanyResults * string
| Exit
type Message =
| ShowSearch
| SearchForCompany of string
| ShowCompanyDetails of OrgNr
| BackToSearchResult
| ExitScreen
| Exited
let view model =
match model with
| StartScreen ->
let selectionOptions = [ "Search for company"; "Exit" ] |> List.map Choice
console {
figlet {
text "Company searcher 2000"
aligned Left
}
let choice =
selection {
title "Choose action"
choices selectionOptions
}
return
match choice with
| Choice "Exit" -> Message.ExitScreen
| Choice _ -> Message.ShowSearch
}
| SearchCompany ->
console {
let validator =
Some
<| (fun (answer: string) ->
if answer.Length < 3 then
Spectre.Console.ValidationResult.Error("Search must be at least 3 characters")
else
Spectre.Console.ValidationResult.Success())
let searchTerm =
textPrompt {
question "Search for company name: "
validation validator
}
return searchTerm |> SearchForCompany
}
| NoCompanyFound searchTerm ->
console {
error { description $"No company found for search term {searchTerm}" }
return ShowSearch
}
| SearchCompanyResult searchResults ->
let selectionOptions =
(searchResults.SearchResult
|> Seq.map (fun result -> $"{result.OrgNr |> OrgNr.value} {result.Name}" |> Choice)
|> Seq.toList)
@ [ "New search" |> Choice; "Exit" |> Choice ]
console {
let choice =
selection {
title "Search results, select company to view details"
choices selectionOptions
}
return
match choice with
| Choice "New search" -> ShowSearch
| Choice "Exit" -> ExitScreen
| Choice companyname ->
let orgnr = companyname[0..9]
orgnr |> OrgNr |> Message.ShowCompanyDetails
}
| CompanyDetails(_, jsonString) ->
let selectionOptions = [ "Back"; "New Search"; "Exit" ] |> List.map Choice
console {
jsonView { json jsonString }
let choice =
selection {
title "What now?"
choices selectionOptions
}
return
match choice with
| Choice "Back" -> BackToSearchResult
| Choice "New Search" -> ShowSearch
| Choice "Exit" -> ExitScreen
| _ -> failwith "Invalid choice"
}
| Exit ->
console {
figlet {
text "K. Thanks. Bye!"
aligned Left
}
return Exited
}
let update model message =
match message with
| ShowSearch -> Model.SearchCompany |> Some
| SearchForCompany searchTerm ->
let searchResult =
searchTerm
|> Brreg.search
|> Array.truncate 10
|> Array.map (fun r ->
{ Name = r.Navn
OrgNr = r.OrgNr |> string |> OrgNr })
match searchResult.Length with
| 0 -> searchTerm |> NoCompanyFound |> Some
| _ ->
{ SearchTerm = searchTerm
SearchResult = searchResult }
|> SearchCompanyResult
|> Some
| BackToSearchResult ->
match model with
| CompanyDetails(searchResult, _) -> searchResult |> Model.SearchCompanyResult |> Some
| _ -> failwith "Invalid state transition"
| ShowCompanyDetails(OrgNr orgnr) ->
match model with
| SearchCompanyResult searchResult ->
let companyDetails = orgnr |> Brreg.companyDetails
(searchResult, companyDetails) |> CompanyDetails |> Some
| _ -> failwith "Invalid state transition"
| ExitScreen -> Model.Exit |> Some
| Exited -> None
[<EntryPoint>]
let main _ =
let rec mvuLoop model =
match model |> view |> update model with
| Some newModel -> newModel |> mvuLoop
| None -> ()
mvuLoop StartScreen
System.Console.ReadLine() |> ignore
0