From 57c308d011a4de95ceeedc5d2a7d5d98e779dd24 Mon Sep 17 00:00:00 2001 From: ge Date: Sun, 22 Dec 2024 05:22:17 +0300 Subject: [PATCH] init --- .editorconfig | 8 ++ .gitattributes | 8 ++ .gitignore | 26 ++++++ Makefile | 23 +++++ README.md | 18 ++++ UNLICENSE | 24 ++++++ cmd/dataunit.v | 130 ++++++++++++++++++++++++++++ src/dataunits.v | 197 +++++++++++++++++++++++++++++++++++++++++++ tests/convert_test.v | 12 +++ v.mod | 7 ++ 10 files changed, 453 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 UNLICENSE create mode 100644 cmd/dataunit.v create mode 100644 src/dataunits.v create mode 100644 tests/convert_test.v create mode 100644 v.mod diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..01072ca --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.v] +indent_style = tab diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9a98968 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +* text=auto eol=lf +*.bat eol=crlf + +*.v linguist-language=V +*.vv linguist-language=V +*.vsh linguist-language=V +v.mod linguist-language=V +.vdocignore linguist-language=ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..21da90b --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +# Binaries for programs and plugins +main +dataunit +*.exe +*.exe~ +*.so +*.dylib +*.dll + +# Ignore binary output folders +bin/ + +# Ignore common editor/system specific metadata +.DS_Store +.idea/ +.vscode/ +*.iml + +# ENV +.env + +# vweb and database +*.db +*.js + +doc diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e3488b0 --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +SRC_DIR ?= src +DOC_DIR ?= doc +TESTS_DIR ?= . + +all: test + +test: + v test $(TESTS_DIR) + +doc: + v doc -f html -m ./$(SRC_DIR) -o $(DOC_DIR) + +serve: clean doc + v -e "import net.http.file; file.serve(folder: '$(DOC_DIR)')" + +build: + v -path "$$(realpath $$PWD/../)|@vlib|@vmodules" \ + -prod -skip-unused -parallel-cc -cflags -static -cflags -s -d no_segfault_handler \ + cmd/dataunit.v -o dataunit + +clean: + rm -r $(DOC_DIR) || true + rm dataunit || true diff --git a/README.md b/README.md new file mode 100644 index 0000000..07dfa1a --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +## Data units converter + +Example: + +```v +import dataunits + +fn main() { + kilobytes := dataunits.convert(500, dataunits.mbit, dataunits.kb) + println(kilobytes) // 62500 + + mebibytes := (dataunits.gib * 15).mib() + println(mebibytes) // 15360 + + bytes := dataunits.DataSize(2000 * dataunits.gib).bytes() + println(bytes) // 4.294967296e+12 == 4294967296000 +} +``` diff --git a/UNLICENSE b/UNLICENSE new file mode 100644 index 0000000..efb9808 --- /dev/null +++ b/UNLICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/cmd/dataunit.v b/cmd/dataunit.v new file mode 100644 index 0000000..7c8387e --- /dev/null +++ b/cmd/dataunit.v @@ -0,0 +1,130 @@ +// This is free and unencumbered software released into the public domain. + +// Anyone is free to copy, modify, publish, use, compile, sell, or +// distribute this software, either in source code form or as a compiled +// binary, for any purpose, commercial or non-commercial, and by any +// means. + +// In jurisdictions that recognize copyright laws, the author or authors +// of this software dedicate any and all copyright interest in the +// software to the public domain. We make this dedication for the benefit +// of the public at large and to the detriment of our heirs and +// successors. We intend this dedication to be an overt act of +// relinquishment in perpetuity of all present and future rights to this +// software under copyright law. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +// For more information, please refer to + +/* + dataunit - a simple CLI tool for data units convertion. +*/ + +module main + +import os +import flag +import dataunits + +const units = { + 'bit': dataunits.bit + 'nibble': dataunits.nibble + 'bytes': dataunits.bytes + 'kb': dataunits.kb + 'mb': dataunits.mb + 'gb': dataunits.gb + 'tb': dataunits.tb + 'pb': dataunits.pb + 'zb': dataunits.zb + 'yb': dataunits.yb + 'kib': dataunits.kib + 'mib': dataunits.mib + 'gib': dataunits.gib + 'tib': dataunits.tib + 'pib': dataunits.pib + 'zib': dataunits.zib + 'yib': dataunits.yib + 'kbit': dataunits.kbit + 'mbit': dataunits.mbit + 'gbit': dataunits.gbit + 'tbit': dataunits.tbit + 'pbit': dataunits.pbit + 'zbit': dataunits.zbit + 'ybit': dataunits.ybit + 'kibit': dataunits.kibit + 'mibit': dataunits.mibit + 'gibit': dataunits.gibit + 'tibit': dataunits.tibit + 'pibit': dataunits.pibit + 'zibit': dataunits.zibit + 'yibit': dataunits.yibit +} + +fn units_str() string { + mut str := []string{} + for key, _ in units { + str << key + } + return str.join(', ') +} + +@[name: 'dataunit'] +struct FlagConfig { + help bool + from string @[short: f] + to string @[short: t] +mut: + value f64 @[ignore] +} + +fn main() { + mut flags, no_matches := flag.to_struct[FlagConfig](os.args, skip: 1, style: .v) or { + eprintln('cmdline parsing error, see -help for info') + exit(2) + } + if no_matches.len > 1 { + eprintln('unrecognized arguments: ${no_matches[1..]}') + exit(2) + } else if no_matches.len == 1 { + flags.value = no_matches[0].f64() + } + if flags.help { + println('convert the value between *from* and *to* units.') + println('usage: dataunit -f -t ') + println('options:') + println(' -help print this help message and exit') + println(' -f, -from source data unit') + println(' -t, -to destination data unit') + exit(0) + } + if flags.from == '' || flags.to == '' { + eprintln('no -from or -to flag set, see -help for info') + exit(2) + } + if flags.value == 0 { + eprintln('no value passed, see -help for info') + exit(2) + } + unit_from := units[flags.from.to_lower()] or { + eprintln('invalid unit ${flags.from}, valid ones: ${units_str()}') + exit(1) + } + unit_to := units[flags.to.to_lower()] or { + eprintln('invalid unit ${flags.to}, valid ones: ${units_str()}') + exit(1) + } + result := '${dataunits.convert(flags.value, unit_from, unit_to):.20f}' + splitted := result.split('.') + if splitted[1].contains_only('0') { + println(splitted[0]) + } else { + println(result.trim_right('0')) + } +} diff --git a/src/dataunits.v b/src/dataunits.v new file mode 100644 index 0000000..eab2a1b --- /dev/null +++ b/src/dataunits.v @@ -0,0 +1,197 @@ +// This is free and unencumbered software released into the public domain. + +// Anyone is free to copy, modify, publish, use, compile, sell, or +// distribute this software, either in source code form or as a compiled +// binary, for any purpose, commercial or non-commercial, and by any +// means. + +// In jurisdictions that recognize copyright laws, the author or authors +// of this software dedicate any and all copyright interest in the +// software to the public domain. We make this dedication for the benefit +// of the public at large and to the detriment of our heirs and +// successors. We intend this dedication to be an overt act of +// relinquishment in perpetuity of all present and future rights to this +// software under copyright law. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +// For more information, please refer to + +module dataunits + +pub type DataSize = f64 + +pub fn (d DataSize) bits() f64 { + return f64(d) +} + +pub fn (d DataSize) nibble() f64 { + return f64(d / nibble) +} + +pub fn (d DataSize) bytes() f64 { + return f64(d / bytes) +} + +pub fn (d DataSize) kb() f64 { + return f64(d / kb) +} + +pub fn (d DataSize) mb() f64 { + return f64(d / mb) +} + +pub fn (d DataSize) gb() f64 { + return f64(d / gb) +} + +pub fn (d DataSize) tb() f64 { + return f64(d / tb) +} + +pub fn (d DataSize) pb() f64 { + return f64(d / pb) +} + +pub fn (d DataSize) zb() f64 { + return f64(d / zb) +} + +pub fn (d DataSize) yb() f64 { + return f64(d / yb) +} + +pub fn (d DataSize) kib() f64 { + return f64(d / kib) +} + +pub fn (d DataSize) mib() f64 { + return f64(d / mib) +} + +pub fn (d DataSize) gib() f64 { + return f64(d / gib) +} + +pub fn (d DataSize) tib() f64 { + return f64(d / tib) +} + +pub fn (d DataSize) pib() f64 { + return f64(d / pib) +} + +pub fn (d DataSize) zib() f64 { + return f64(d / zib) +} + +pub fn (d DataSize) yib() f64 { + return f64(d / yib) +} + +pub fn (d DataSize) kbit() f64 { + return f64(d / kbit) +} + +pub fn (d DataSize) mbit() f64 { + return f64(d / mbit) +} + +pub fn (d DataSize) gbit() f64 { + return f64(d / gbit) +} + +pub fn (d DataSize) tbit() f64 { + return f64(d / tbit) +} + +pub fn (d DataSize) pbit() f64 { + return f64(d / pbit) +} + +pub fn (d DataSize) zbit() f64 { + return f64(d / zbit) +} + +pub fn (d DataSize) ybit() f64 { + return f64(d / ybit) +} + +pub fn (d DataSize) kibit() f64 { + return f64(d / kibit) +} + +pub fn (d DataSize) mibit() f64 { + return f64(d / mibit) +} + +pub fn (d DataSize) gibit() f64 { + return f64(d / gibit) +} + +pub fn (d DataSize) tibit() f64 { + return f64(d / tibit) +} + +pub fn (d DataSize) pibit() f64 { + return f64(d / pibit) +} + +pub fn (d DataSize) zibit() f64 { + return f64(d / zibit) +} + +pub fn (d DataSize) yibit() f64 { + return f64(d / yibit) +} + +pub const bit = DataSize(1) +pub const nibble = bit * 4 +pub const bytes = bit * 8 + +pub const kb = bytes * 1000 +pub const mb = kb * 1000 +pub const gb = mb * 1000 +pub const tb = gb * 1000 +pub const pb = tb * 1000 +pub const zb = tb * 1000 +pub const yb = zb * 1000 + +pub const kib = bytes * 1024 +pub const mib = kib * 1024 +pub const gib = mib * 1024 +pub const tib = gib * 1024 +pub const pib = tib * 1024 +pub const zib = tib * 1024 +pub const yib = zib * 1024 + +pub const kbit = bit * 1000 +pub const mbit = kbit * 1000 +pub const gbit = mbit * 1000 +pub const tbit = gbit * 1000 +pub const pbit = tbit * 1000 +pub const zbit = pbit * 1000 +pub const ybit = zbit * 1000 + +pub const kibit = bit * 1024 +pub const mibit = kibit * 1024 +pub const gibit = mibit * 1024 +pub const tibit = gibit * 1024 +pub const pibit = tibit * 1024 +pub const zibit = tibit * 1024 +pub const yibit = zibit * 1024 + +// convert returns the value converted between the *from* and *to* units. +// Example: +// ``` +// assert dataunits.convert(500, dataunits.mbit, dataunits.kb) == 62500 +// ```` +pub fn convert(value f64, from DataSize, to DataSize) f64 { + return f64(value * from / to) +} diff --git a/tests/convert_test.v b/tests/convert_test.v new file mode 100644 index 0000000..0f666e1 --- /dev/null +++ b/tests/convert_test.v @@ -0,0 +1,12 @@ +import dataunits + +fn test_convert() { + assert (dataunits.nibble * 4).bytes() == 2 + assert (dataunits.bit * 8).bits() == 8 + assert (dataunits.bit * 8).bytes() == 1 + assert (dataunits.gib * 10).mib() == 10240 + assert (dataunits.gib * 5000).bytes() == i64(5368709120000) + assert (dataunits.mbit * 500).kb() == 62500 + assert dataunits.convert(500, dataunits.mbit, dataunits.kb) == 62500 + assert dataunits.DataSize(4000 * dataunits.gib).bytes() == f64(4294967296000) +} diff --git a/v.mod b/v.mod new file mode 100644 index 0000000..7f49da3 --- /dev/null +++ b/v.mod @@ -0,0 +1,7 @@ +Module { + name: 'dataunits' + description: 'Data units converter' + version: '0.0.1' + license: 'Unlicense' + dependencies: [] +}