ocaml-fun/bin/main.ml

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