rfc7565.ml 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. (*
  2. * _ _ ____ _
  3. * _| || |_/ ___| ___ _ __ _ __ ___ | |
  4. * |_ .. _\___ \ / _ \ '_ \| '_ \ / _ \| |
  5. * |_ _|___) | __/ |_) | |_) | (_) |_|
  6. * |_||_| |____/ \___| .__/| .__/ \___/(_)
  7. * |_| |_|
  8. *
  9. * Personal Social Web.
  10. *
  11. * Copyright (C) The #Seppo contributors. All rights reserved.
  12. *
  13. * This program is free software: you can redistribute it and/or modify
  14. * it under the terms of the GNU General Public License as published by
  15. * the Free Software Foundation, either version 3 of the License, or
  16. * (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  25. *)
  26. (* https://datatracker.ietf.org/doc/html/rfc7565 *)
  27. type t = T of Uri.t
  28. let scheme = "acct"
  29. let of_uri u =
  30. assert ("acct" |> String.equal scheme);
  31. match
  32. u |> Uri.scheme,
  33. u |> Uri.user,
  34. u |> Uri.host,
  35. u |> Uri.port,
  36. u |> Uri.path,
  37. u |> Uri.query,
  38. u |> Uri.fragment
  39. with
  40. | Some "acct",
  41. Some _,
  42. Some _,
  43. None,
  44. "",
  45. [],
  46. None
  47. -> Some (T u)
  48. | _
  49. -> None
  50. let make ~local ~domain () =
  51. match Uri.make
  52. ~scheme
  53. ~userinfo:local
  54. ~host:domain
  55. ()
  56. |> of_uri with
  57. | None ->
  58. Printf.sprintf "%s @%s@%s" __LOC__ local domain
  59. |> failwith
  60. | Some u -> u
  61. let rx_scheme = scheme ^ {|:\|@|}
  62. let rx_user = {|[^@: ]+|}
  63. let rx_host = {|[^ :/\?#]+|}
  64. let rx' = {|^\(|} ^ rx_scheme ^ {|\)?\(|} ^ rx_user ^ {|\)@\(|} ^ rx_host ^ {|\)$|}
  65. let rx = rx' |> Str.regexp
  66. let of_string s =
  67. if not (Str.string_match rx s 0)
  68. then Error ("doesn't match /" ^ rx' ^ "/")
  69. else
  70. Ok (make
  71. ~local:(Str.matched_group 2 s)
  72. ~domain:(Str.matched_group 3 s)
  73. () )
  74. let to_string ?(prefix = scheme ^ ":") (T u) =
  75. Printf.sprintf "%s%s@%s"
  76. prefix
  77. (u |> Uri.user |> Option.value ~default:"")
  78. (u |> Uri.host |> Option.value ~default:"")
  79. let pp_hum ppf uri = Format.pp_print_string ppf (to_string ~prefix:"@" uri)