From f58221e6cdc28dfbc2102968ff71aea9d872696a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Krzy=C5=BCanowski?= Date: Sun, 9 Feb 2025 23:30:24 +0100 Subject: [PATCH] Initial commit --- .gitignore | 1 + bin/dune | 4 ++ bin/main.ml | 121 +++++++++++++++++++++++++++++++++++++++ dune-project | 26 +++++++++ lib/dune | 2 + test/dune | 2 + test/test_time_master.ml | 0 time_master.opam | 31 ++++++++++ 8 files changed, 187 insertions(+) create mode 100644 .gitignore create mode 100644 bin/dune create mode 100644 bin/main.ml create mode 100644 dune-project create mode 100644 lib/dune create mode 100644 test/dune create mode 100644 test/test_time_master.ml create mode 100644 time_master.opam diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..69fa449 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +_build/ diff --git a/bin/dune b/bin/dune new file mode 100644 index 0000000..973890b --- /dev/null +++ b/bin/dune @@ -0,0 +1,4 @@ +(executable + (public_name time_master) + (name main) + (libraries time_master)) diff --git a/bin/main.ml b/bin/main.ml new file mode 100644 index 0000000..730a42b --- /dev/null +++ b/bin/main.ml @@ -0,0 +1,121 @@ +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 diff --git a/dune-project b/dune-project new file mode 100644 index 0000000..c1a0831 --- /dev/null +++ b/dune-project @@ -0,0 +1,26 @@ +(lang dune 3.17) + +(name time_master) + +(generate_opam_files true) + +(source + (github username/reponame)) + +(authors "Author Name ") + +(maintainers "Maintainer Name ") + +(license LICENSE) + +(documentation https://url/to/documentation) + +(package + (name time_master) + (synopsis "A short synopsis") + (description "A longer description") + (depends ocaml) + (tags + ("add topics" "to describe" your project))) + +; See the complete stanza docs at https://dune.readthedocs.io/en/stable/reference/dune-project/index.html diff --git a/lib/dune b/lib/dune new file mode 100644 index 0000000..409db77 --- /dev/null +++ b/lib/dune @@ -0,0 +1,2 @@ +(library + (name time_master)) diff --git a/test/dune b/test/dune new file mode 100644 index 0000000..327aa4b --- /dev/null +++ b/test/dune @@ -0,0 +1,2 @@ +(test + (name test_time_master)) diff --git a/test/test_time_master.ml b/test/test_time_master.ml new file mode 100644 index 0000000..e69de29 diff --git a/time_master.opam b/time_master.opam new file mode 100644 index 0000000..aed4d6e --- /dev/null +++ b/time_master.opam @@ -0,0 +1,31 @@ +# This file is generated by dune, edit dune-project instead +opam-version: "2.0" +synopsis: "A short synopsis" +description: "A longer description" +maintainer: ["Maintainer Name "] +authors: ["Author Name "] +license: "LICENSE" +tags: ["add topics" "to describe" "your" "project"] +homepage: "https://github.com/username/reponame" +doc: "https://url/to/documentation" +bug-reports: "https://github.com/username/reponame/issues" +depends: [ + "dune" {>= "3.17"} + "ocaml" + "odoc" {with-doc} +] +build: [ + ["dune" "subst"] {dev} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] +] +dev-repo: "git+https://github.com/username/reponame.git"