parse comma separated targets into individual commands

This commit is contained in:
tali 2024-01-11 00:13:08 -05:00
parent 1f81abfad2
commit f383706931
1 changed files with 38 additions and 24 deletions

View File

@ -155,7 +155,6 @@ let on_msg_user t username realname =
let on_msg_privmsg t tgt txt =
let* me = require_registered t in
(* TODO: comma-separated list of targets *)
let* dst =
try
match Irc.name_type tgt with
@ -184,7 +183,6 @@ let list_names t chan =
let on_msg_names t name =
let* _me = require_registered t in
(* TODO: comma-separated list of channels *)
let* chan =
try
match Irc.name_type name with
@ -199,7 +197,7 @@ let on_msg_names t name =
let on_msg_join t name =
let* me = require_registered t in
(* TODO: comma-separated list of channels *)
(* TODO: keys parameter *)
(* TODO: "0" parameter means part from all channels *)
let* chan =
try
@ -213,7 +211,7 @@ let on_msg_join t name =
(* TODO: make user +o *)
Ok chan
in
(* TODO: check if channel is +k, get associated key from parameters *)
(* TODO: check if channel is +k *)
Chan.join chan me;
let msg = Irc.Msg.make "JOIN" [name] in
Router.relay msg ~from:me `to_self;
@ -264,24 +262,40 @@ let on_msg_quit t reason =
(* message parsing *)
let dispatch t = function
| "NICK", nick :: _ when nick <> "" -> on_msg_nick t nick
| "NICK", _ -> Error nonicknamegiven
| "USER", unm :: _ :: _ :: rnm :: _ -> on_msg_user t unm rnm
| "QUIT", why -> on_msg_quit t why
| "MOTD", _ -> on_msg_motd t
| "PRIVMSG", tgt :: msg :: _ -> on_msg_privmsg t tgt msg
| "PRIVMSG", [_] -> Error notexttosend | "PRIVMSG", [] -> Error norecipient
| "JOIN", tgt :: _ when tgt <> "" -> on_msg_join t tgt
| "NAMES", tgt :: _ when tgt <> "" -> on_msg_names t tgt
| "PART", tgt :: _ when tgt <> "" -> on_msg_part t tgt
| ("USER" | "JOIN" | "NAMES" | "PART") as cmd, _ ->
Error (needmoreparams cmd)
| cmd, _ ->
Error (unknowncommand cmd)
let split_command_params cmd params =
match cmd, params with
| ("PRIVMSG" | "JOIN" | "NAMES" | "PART"), tgts :: rest
when String.contains tgts ',' ->
(* TODO: "JOIN" should be handled specially *)
String.split_on_char ',' tgts |>
List.map (fun tgt -> cmd, tgt :: rest)
| _ ->
[cmd, params]
let pp_args ppf (cmd, params) =
Fmt.pf ppf "%s %a" cmd (Fmt.list (Fmt.fmt "%S") ~sep:Fmt.sp) params
let on_msg t (msg : Irc.Msg.t) : unit =
(* Logs.debug (fun m -> m "%a: %a" pp_sockaddr t.addr Irc.Msg.pp msg); *)
let result =
match msg.command, msg.params with
| "NICK", nick :: _ when nick <> "" -> on_msg_nick t nick
| "NICK", _ -> Error nonicknamegiven
| "USER", unm :: _ :: _ :: rnm :: _ -> on_msg_user t unm rnm
| "QUIT", why -> on_msg_quit t why
| "MOTD", _ -> on_msg_motd t
| "PRIVMSG", tgt :: msg :: _ -> on_msg_privmsg t tgt msg
| "PRIVMSG", [_] -> Error notexttosend | "PRIVMSG", [] -> Error norecipient
| "JOIN", tgt :: _ when tgt <> "" -> on_msg_join t tgt
| "NAMES", tgt :: _ when tgt <> "" -> on_msg_names t tgt
| "PART", tgt :: _ when tgt <> "" -> on_msg_part t tgt
| "USER", _ | "JOIN", _ | "NAMES", _ | "PART", _ ->
Error (needmoreparams msg.command)
| _, _ -> Error (unknowncommand msg.command)
in
match result with
| Ok () -> ()
| Error err -> reply t err
split_command_params msg.command msg.params |>
List.iter
(fun args ->
Logs.debug (fun m -> m "%a: %a" pp_sockaddr t.addr pp_args args);
match dispatch t args with
| Ok () -> ()
| Error err -> reply t err)