13
13
| Readme of string
14
14
| Raw_file of string * string
15
15
16
-
Removed:
let%path root_path = "/"
17
-
Removed:
let%path repo_root_path = "/%s/"
18
-
Removed:
let%path repo_path = "/%s/summary/"
19
-
Removed:
let%path commits_path = "/%s/commits/"
20
-
Removed:
let%path commits_branch_path = "/%s/commits/%s"
21
-
Removed:
let%path commit_path = "/%s/commit/%s"
22
-
Removed:
let%path files_path = "/%s/files/"
23
-
Removed:
let%path file_path = "/%s/file/%s"
24
-
Removed:
let%path branches_path = "/%s/branches/"
25
-
Removed:
let%path tags_path = "/%s/tags/"
26
-
Removed:
let%path readme_path = "/%s/README"
27
-
Removed:
let%path raw_file_path = "/%s/raw/%s"
28
-
Removed:
let%path static_path = "/static/%*s"
16
+
Added:
let root_path = "/"
17
+
Added:
let static_prefix = "/static/"
29
18
19
+
Added:
(* Generate URL paths for routes *)
20
+
Added:
let path_of = function
21
+
Added:
| Root -> "/"
22
+
Added:
| Repo repo -> "/" ^ repo ^ "/summary/"
23
+
Added:
| Commits repo -> "/" ^ repo ^ "/commits/"
24
+
Added:
| Commits_branch (repo, branch) -> "/" ^ repo ^ "/commits/" ^ branch
25
+
Added:
| Commit (repo, hash) -> "/" ^ repo ^ "/commit/" ^ hash
26
+
Added:
| Files repo -> "/" ^ repo ^ "/files/"
27
+
Added:
| File (repo, hash) -> "/" ^ repo ^ "/file/" ^ hash
28
+
Added:
| Branches repo -> "/" ^ repo ^ "/branches/"
29
+
Added:
| Tags repo -> "/" ^ repo ^ "/tags/"
30
+
Added:
| Readme repo -> "/" ^ repo ^ "/README"
31
+
Added:
| Raw_file (repo, hash) -> "/" ^ repo ^ "/raw/" ^ hash
32
+
Added:
30
33
let link_to route ?(other_attrs = []) contents =
31
34
let open Dream_html in
32
35
let open HTML in
33
-
Removed:
let path = function
34
-
Removed:
| Root -> path_attr href root_path
35
-
Removed:
| Repo repo -> path_attr href repo_path repo
36
-
Removed:
| Commits repo -> path_attr href commits_path repo
37
-
Removed:
| Commits_branch (repo, branch) ->
38
-
Removed:
path_attr href commits_branch_path repo branch
39
-
Removed:
| Commit (repo, commit) -> path_attr href commit_path repo commit
40
-
Removed:
| Files repo -> path_attr href files_path repo
41
-
Removed:
| File (repo, hash) -> path_attr href file_path repo hash
42
-
Removed:
| Branches repo -> path_attr href branches_path repo
43
-
Removed:
| Tags repo -> path_attr href tags_path repo
44
-
Removed:
| Readme repo -> path_attr href readme_path repo
45
-
Removed:
| Raw_file (repo, hash) -> path_attr href raw_file_path repo hash
36
+
Added:
a (href "%s" (path_of route) :: other_attrs) [ contents ]
37
+
Added:
38
+
Added:
(** Dispatch a request path (without leading slash) into a route. Returns
39
+
Added:
[(repo_name, action, param)] where action identifies what to do. *)
40
+
Added:
type action =
41
+
Added:
| Summary
42
+
Added:
| Commits_page
43
+
Added:
| Commits_for_branch of string
44
+
Added:
| Commit_detail of string
45
+
Added:
| Files_page
46
+
Added:
| File_detail of string
47
+
Added:
| Branches_page
48
+
Added:
| Tags_page
49
+
Added:
| Readme_page
50
+
Added:
| Raw of string
51
+
Added:
52
+
Added:
let known_actions =
53
+
Added:
[
54
+
Added:
"summary";
55
+
Added:
"commits";
56
+
Added:
"commit";
57
+
Added:
"files";
58
+
Added:
"file";
59
+
Added:
"branches";
60
+
Added:
"tags";
61
+
Added:
"README";
62
+
Added:
"raw";
63
+
Added:
]
64
+
Added:
65
+
Added:
let dispatch path =
66
+
Added:
(* path is the full URL path without leading slash, e.g. "sub/repo/commits/" *)
67
+
Added:
let segments =
68
+
Added:
String.split_on_char '/' path |> List.filter (fun s -> s <> "")
46
69
in
47
-
Removed:
a (path route :: other_attrs) [ contents ]
70
+
Added:
(* Try to find the split point: the last segment that matches a known action *)
71
+
Added:
let rec find_split repo_acc = function
72
+
Added:
| [] ->
73
+
Added:
(* No action found — treat the whole path as repo with implicit summary *)
74
+
Added:
let repo = String.concat "/" (List.rev repo_acc) in
75
+
Added:
if repo = "" then None else Some (repo, Summary)
76
+
Added:
| seg :: rest when List.mem seg known_actions ->
77
+
Added:
let repo = String.concat "/" (List.rev repo_acc) in
78
+
Added:
if repo = "" then None
79
+
Added:
else
80
+
Added:
let action =
81
+
Added:
match (seg, rest) with
82
+
Added:
| "summary", _ -> Summary
83
+
Added:
| "commits", [] -> Commits_page
84
+
Added:
| "commits", [ branch ] -> Commits_for_branch branch
85
+
Added:
| "commit", [ hash ] -> Commit_detail hash
86
+
Added:
| "files", _ -> Files_page
87
+
Added:
| "file", [ hash ] -> File_detail hash
88
+
Added:
| "branches", _ -> Branches_page
89
+
Added:
| "tags", _ -> Tags_page
90
+
Added:
| "README", _ -> Readme_page
91
+
Added:
| "raw", [ hash ] -> Raw hash
92
+
Added:
| _ -> Summary
93
+
Added:
in
94
+
Added:
Some (repo, action)
95
+
Added:
| seg :: rest -> find_split (seg :: repo_acc) rest
96
+
Added:
in
97
+
Added:
find_split [] segments