122 lines
3.4 KiB
OCaml
122 lines
3.4 KiB
OCaml
type command = {
|
|
name : string;
|
|
args : string list
|
|
}
|
|
|
|
type context = {
|
|
counter : int
|
|
}
|
|
|
|
type request =
|
|
| Hello of string
|
|
| GetCtx
|
|
| Inc;;
|
|
|
|
type response =
|
|
| Hello of string
|
|
| GetCtx of context
|
|
| Inc;;
|
|
|
|
let parse_cmd cmd_line : command =
|
|
let cmd_split = String.split_on_char ' ' cmd_line
|
|
in {name = List.hd cmd_split; args = List.tl cmd_split};;
|
|
|
|
let print_cmd cmd : unit =
|
|
Printf.printf "Command [%s]\n" cmd.name;
|
|
List.iteri (Printf.printf "\tArg [%d] -> %s\n") cmd.args;;
|
|
|
|
let print_ctx (ctx: context) : unit =
|
|
Printf.printf "Context [counter] = %d\n" ctx.counter;;
|
|
|
|
let request_of_cmd (cmd: command) : (request, string) result =
|
|
match cmd.name with
|
|
| "hello" -> Ok (Hello ("Hello, " ^ (String.concat "," cmd.args)))
|
|
| "getctx" -> Ok (GetCtx)
|
|
| "inc" -> Ok (Inc)
|
|
| _ -> Error "Unkown command name";;
|
|
|
|
let response_print (res: response) =
|
|
match res with
|
|
| Hello text -> print_endline text
|
|
| GetCtx ctx -> print_ctx ctx
|
|
| Inc -> print_endline "Incremented!";;
|
|
|
|
let handle_request (ctx: context) (req: request) : context * response =
|
|
match req with
|
|
| Hello txt -> ctx, Hello txt
|
|
| GetCtx -> (ctx, GetCtx ctx)
|
|
| Inc -> { counter = ctx.counter + 1 }, Inc;;
|
|
|
|
let parse_cmds cmd_strs : command list =
|
|
List.map parse_cmd cmd_strs;;
|
|
|
|
let rec print_cmds cmds : unit =
|
|
match cmds with
|
|
| [] -> ()
|
|
| h :: t -> print_cmd h; print_cmds t;;
|
|
|
|
let handle_cmd (ctx: context) (cmd: command) : (context * response, string) result =
|
|
let req = request_of_cmd cmd in
|
|
match req with
|
|
| Ok req -> Ok (handle_request ctx req)
|
|
| Error err -> Error err;;
|
|
|
|
let rec handle_cmds (init_ctx: context) (cmds: command list) : (context, string) result =
|
|
match cmds with
|
|
| [] -> Ok init_ctx
|
|
| cmd :: rest -> (handle_cmds
|
|
(match (handle_cmd init_ctx cmd) with
|
|
| Ok (ctx, res) -> response_print res; ctx
|
|
| Error (str) -> print_endline str; init_ctx)) rest;;
|
|
|
|
let print_handle_result res =
|
|
match res with
|
|
| Ok ctx -> print_ctx ctx
|
|
| Error err -> print_endline err;;
|
|
|
|
let string_lpad (str: string) (pad: char) (width: int) : string =
|
|
let rem = width - String.length str in
|
|
let rec append_left (str: string) (pad: char) (count: int) : string =
|
|
match count with
|
|
| 0 -> str
|
|
| n -> append_left ((String.make 1 pad) ^ str) pad (n - 1)
|
|
in append_left str pad rem;;
|
|
|
|
let string_rpad (str: string) (pad: char) (width: int) : string =
|
|
let rem = width - String.length str in
|
|
let rec append_right (str: string) (pad: char) (count: int) : string =
|
|
match count with
|
|
| 0 -> str
|
|
| n -> append_right (str ^ (String.make 1 pad)) pad (n - 1)
|
|
in append_right str pad rem;;
|
|
|
|
let string_center (s: string) (pad: char) (width : int) : string =
|
|
let str_len = String.length s in
|
|
let side_pad = (width+str_len)/2 in
|
|
string_rpad (string_lpad s pad side_pad) pad width;;
|
|
|
|
let char_repeat (c: char) (times: int) : string =
|
|
string_lpad "" c times;;
|
|
|
|
let print_heading (s: string) : unit =
|
|
print_endline (char_repeat '=' 64);
|
|
print_endline (string_center (string_center s ' ' 32) '=' 64);
|
|
print_endline (char_repeat '=' 64);;
|
|
|
|
let get_init_ctx : context = { counter = 0 };;
|
|
|
|
let cmds = parse_cmds [
|
|
"hello Maciek";
|
|
"getctx";
|
|
"inc";
|
|
"getctx";
|
|
"inc";
|
|
];;
|
|
|
|
print_heading "Command processing";;
|
|
print_cmds cmds;;
|
|
print_heading "Command handling";;
|
|
let final_result = handle_cmds get_init_ctx cmds;;
|
|
print_heading "Final result";;
|
|
print_handle_result final_result
|