This commit is contained in:
ge 2024-12-22 05:22:17 +03:00
commit 57c308d011
10 changed files with 453 additions and 0 deletions

8
.editorconfig Normal file
View File

@ -0,0 +1,8 @@
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.v]
indent_style = tab

8
.gitattributes vendored Normal file
View File

@ -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

26
.gitignore vendored Normal file
View File

@ -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

23
Makefile Normal file
View File

@ -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

18
README.md Normal file
View File

@ -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
}
```

24
UNLICENSE Normal file
View File

@ -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 <https://unlicense.org/>

130
cmd/dataunit.v Normal file
View File

@ -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 <https://unlicense.org/>
/*
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 <unit> -t <unit> <value>')
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'))
}
}

197
src/dataunits.v Normal file
View File

@ -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 <https://unlicense.org/>
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)
}

12
tests/convert_test.v Normal file
View File

@ -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)
}

7
v.mod Normal file
View File

@ -0,0 +1,7 @@
Module {
name: 'dataunits'
description: 'Data units converter'
version: '0.0.1'
license: 'Unlicense'
dependencies: []
}