forked from hexpm/hexdocs-search
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathroute.gleam
More file actions
89 lines (81 loc) · 2.32 KB
/
route.gleam
File metadata and controls
89 lines (81 loc) · 2.32 KB
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
import gleam/bool
import gleam/list
import gleam/option.{None, Some}
import gleam/result
import gleam/string
import gleam/uri.{type Uri}
import hexdocs/data/model/version
import modem
pub type Route {
Home
Search(q: String, packages: List(#(String, String)))
NotFound
}
pub fn from_uri(location: Uri) -> Route {
case uri.path_segments(location.path) {
[] ->
{
use query <- result.try(option.to_result(location.query, Nil))
use parsed_query <- result.try(uri.parse_query(query))
use _ <- result.try(list.key_find(parsed_query, "q"))
Ok(search_from_uri(location))
}
|> result.unwrap(Home)
_ -> NotFound
}
}
pub fn to_uri(route: Route) -> Uri {
let assert Ok(uri) = case route {
Home -> uri.parse("/")
NotFound -> uri.parse("/")
Search(q:, packages:) -> {
use uri <- result.map(uri.parse("/"))
let query = create_query([#("q", q)], packages)
let query = uri.query_to_string(query)
uri.Uri(..uri, query: Some(query))
}
}
uri
}
pub fn push(route: Route) {
let route = to_uri(route)
modem.push(route.path, route.query, route.fragment)
}
pub fn replace(route: Route) {
let route = to_uri(route)
modem.replace(route.path, route.query, route.fragment)
}
fn create_query(
query: List(#(String, String)),
packages: List(#(String, String)),
) -> List(#(String, String)) {
use <- bool.guard(when: list.is_empty(packages), return: query)
let packages = list.map(packages, version.to_string)
let packages = string.join(packages, with: ",")
list.append(query, [#("packages", packages)])
}
fn search_from_uri(location: Uri) {
case location.query {
None -> Search(q: "", packages: [])
Some(query) -> {
case uri.parse_query(query) {
Error(_) -> Search(q: "", packages: [])
Ok(query) -> {
let q = list.key_find(query, "q") |> result.unwrap("")
Search(q:, packages: {
list.key_find(query, "packages")
|> result.unwrap("")
|> string.split(on: ",")
|> list.filter_map(fn(package) {
case version.match_package(package) {
Ok(#(package, Some(version))) -> Ok(#(package, version))
Ok(_) -> Error(Nil)
Error(Nil) -> Error(Nil)
}
})
})
}
}
}
}
}