Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
53a0d77ecb | |||
f4fe18ed49 | |||
8dc59e114c | |||
9206200515 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,6 +1,6 @@
|
||||
# Binaries for programs and plugins
|
||||
main
|
||||
dataunit
|
||||
/dataunit
|
||||
*.exe
|
||||
*.exe~
|
||||
*.so
|
||||
|
4
Makefile
4
Makefile
@ -15,8 +15,8 @@ serve: clean doc
|
||||
|
||||
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
|
||||
-prod -parallel-cc -cflags -static -cflags -s -d no_segfault_handler \
|
||||
cmd/dataunit -o dataunit
|
||||
|
||||
clean:
|
||||
rm -r $(DOC_DIR) || true
|
||||
|
@ -12,13 +12,16 @@ Example:
|
||||
import dataunits
|
||||
|
||||
fn main() {
|
||||
// convert via convert fn
|
||||
kilobytes := dataunits.convert(500, dataunits.mbit, dataunits.kb)
|
||||
println(kilobytes) // 62500.0
|
||||
|
||||
// convert via DataSize method (the arguments order matters)
|
||||
mebibytes := (dataunits.gib * 15).mib()
|
||||
println(mebibytes) // 15360.0
|
||||
|
||||
bytes := dataunits.DataSize(2000 * dataunits.gib).bytes()
|
||||
// convert via DataSize method with explicit type cast
|
||||
bytes := dataunits.DataSize(2000 * dataunits.gib).byte()
|
||||
println(bytes) // 2.147483648e+12 == 2147483648000
|
||||
}
|
||||
```
|
||||
|
@ -70,11 +70,11 @@ fn main() {
|
||||
eprintln('no value passed, see -help for info')
|
||||
exit(2)
|
||||
}
|
||||
src := dataunits.from_string(flags.from, ci: true) or {
|
||||
src := dataunits.from_string(flags.from, case_insensitive: true) or {
|
||||
eprintln('invalid source unit: ${err}')
|
||||
exit(1)
|
||||
}
|
||||
dst := dataunits.from_string(flags.to, ci: true) or {
|
||||
dst := dataunits.from_string(flags.to, case_insensitive: true) or {
|
||||
eprintln('invalid destination unit: ${err}')
|
||||
exit(1)
|
||||
}
|
36
examples/parse_units.v
Normal file
36
examples/parse_units.v
Normal file
@ -0,0 +1,36 @@
|
||||
import os
|
||||
import regex
|
||||
import dataunits
|
||||
|
||||
struct Memory {
|
||||
value f64
|
||||
unit dataunits.DataSize
|
||||
}
|
||||
|
||||
fn (m Memory) str() string {
|
||||
return '${m.value} ${dataunits.to_string(m.unit) or { '' }}'
|
||||
}
|
||||
|
||||
fn (m Memory) mib() f64 {
|
||||
return dataunits.convert(m.value, m.unit, dataunits.mib)
|
||||
}
|
||||
|
||||
fn Memory.from_string(s string) !Memory {
|
||||
mut re := regex.regex_opt(r'^(\d+)([a-zA-Z]+)$')!
|
||||
re.match_string(s)
|
||||
if re.groups.len != 2 {
|
||||
return error("unable to parse string '${s}'")
|
||||
}
|
||||
value := re.get_group_by_id(s, 0).f64()
|
||||
unit := dataunits.from_string(re.get_group_by_id(s, 1))!
|
||||
return Memory{value, unit}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
mem := Memory.from_string(os.input('Enter memory value (e.g. 10Gi): ')) or {
|
||||
eprintln('Error: ${err}')
|
||||
exit(1)
|
||||
}
|
||||
println('Input: ${mem}')
|
||||
println('Memory size: ${mem.mib()} MiB')
|
||||
}
|
@ -37,8 +37,8 @@ pub fn (d DataSize) nibble() f64 {
|
||||
return f64(d / nibble)
|
||||
}
|
||||
|
||||
pub fn (d DataSize) bytes() f64 {
|
||||
return f64(d / bytes)
|
||||
pub fn (d DataSize) byte() f64 {
|
||||
return f64(d / byte)
|
||||
}
|
||||
|
||||
pub fn (d DataSize) kb() f64 {
|
||||
@ -171,9 +171,9 @@ pub fn (d DataSize) yibit() f64 {
|
||||
|
||||
pub const bit = DataSize(1)
|
||||
pub const nibble = bit * 4
|
||||
pub const bytes = bit * 8
|
||||
pub const byte = bit * 8
|
||||
|
||||
pub const kb = bytes * 1000
|
||||
pub const kb = byte * 1000
|
||||
pub const mb = kb * 1000
|
||||
pub const gb = mb * 1000
|
||||
pub const tb = gb * 1000
|
||||
@ -182,7 +182,7 @@ pub const eb = pb * 1000
|
||||
pub const zb = eb * 1000
|
||||
pub const yb = zb * 1000
|
||||
|
||||
pub const kib = bytes * 1024
|
||||
pub const kib = byte * 1024
|
||||
pub const mib = kib * 1024
|
||||
pub const gib = mib * 1024
|
||||
pub const tib = gib * 1024
|
||||
@ -212,7 +212,7 @@ pub const yibit = zibit * 1024
|
||||
const units = {
|
||||
'bit': bit
|
||||
'nibble': nibble
|
||||
'bytes': bytes
|
||||
'byte': byte
|
||||
'kB': kb
|
||||
'MB': mb
|
||||
'GB': gb
|
||||
@ -282,22 +282,22 @@ pub fn convert(value f64, from DataSize, to DataSize) f64 {
|
||||
|
||||
// from_string parses input and returns the actual DataSize.
|
||||
// Note: Case insensitivity makes unit abbreviations such as `Mb` (megabit) and `MB` (megabyte)
|
||||
// ambiguous. Use `bit` suffix for bit units. The `b` suffix will be accepted as byte unit.
|
||||
// ambiguous. Use `bit` suffix for values in bits. The `b` suffix will be accepted as byte unit.
|
||||
// Example:
|
||||
// ```
|
||||
// assert dataunits.from_string('GiB')! == dataunits.gib
|
||||
// assert dataunits.from_string('M')! == dataunits.mib
|
||||
// assert dataunits.from_string('M', bits: true, metric: true)! == dataunits.mbit
|
||||
// assert dataunits.from_string('ZeTtAbYtEs', ci: true)! == dataunits.zb
|
||||
// assert dataunits.from_string('M')! == dataunits.mb
|
||||
// assert dataunits.from_string('M', in_bits: true)! == dataunits.mbit
|
||||
// assert dataunits.from_string('ZeTtAbYtEs', case_insensitive: true)! == dataunits.zb
|
||||
// ```
|
||||
pub fn from_string(input string, params ParseParams) !DataSize {
|
||||
if !input.is_pure_ascii() {
|
||||
return error('${input} non-ASCII characters is not allowed in data size unit')
|
||||
}
|
||||
unit := parse_unit_str(input, params)
|
||||
if params.ci {
|
||||
if params.case_insensitive {
|
||||
for key, value in units {
|
||||
if key.to_lower_ascii() == unit {
|
||||
if key.to_lower_ascii() == unit.to_lower_ascii() {
|
||||
return value
|
||||
}
|
||||
}
|
||||
@ -309,45 +309,52 @@ fn parse_unit_str(input string, params ParseParams) string {
|
||||
mut unit := ''
|
||||
match true {
|
||||
input.to_lower_ascii() in ['byte', 'bytes'] {
|
||||
return 'bytes'
|
||||
return 'byte'
|
||||
}
|
||||
input.to_lower_ascii() in ['bit', 'bits'] {
|
||||
return 'bit'
|
||||
}
|
||||
input.len == 1 {
|
||||
if params.metric {
|
||||
unit = input
|
||||
} else {
|
||||
if params.binary_size {
|
||||
unit = input.to_upper_ascii() + 'i'
|
||||
} else {
|
||||
unit = input
|
||||
}
|
||||
if params.bits {
|
||||
if params.in_bits {
|
||||
unit += 'bit'
|
||||
} else {
|
||||
unit += 'B'
|
||||
}
|
||||
return unit
|
||||
}
|
||||
input.len == 2 && input[1] == u8(`b`) && params.ci == false {
|
||||
if input[0] != u8(`k`) {
|
||||
return input[..1] + 'bit'
|
||||
input.len == 2 && input[1] == u8(`i`) {
|
||||
if params.in_bits {
|
||||
return input + 'bit'
|
||||
}
|
||||
return input[..1].to_upper_ascii() + 'bit'
|
||||
return input + 'B'
|
||||
}
|
||||
input.len == 3 && input.ends_with('ib') && params.case_insensitive == false {
|
||||
// Mib -> Mibit
|
||||
return input[..2] + 'bit'
|
||||
}
|
||||
input.len == 2 && input[1] == u8(`b`) && params.case_insensitive == false {
|
||||
// Mb -> Mbit
|
||||
return input[..1] + 'bit'
|
||||
}
|
||||
else {
|
||||
unit = input
|
||||
}
|
||||
}
|
||||
if params.ci {
|
||||
if params.case_insensitive {
|
||||
unit = unit.to_lower_ascii()
|
||||
}
|
||||
if unit.len == 5 && unit.ends_with('ibit') {
|
||||
// prevent Gibit --> Git transform
|
||||
return unit
|
||||
}
|
||||
unit = unit.replace_each(maps.flat_map[string, string, string](prefixes, |k, v| [
|
||||
k,
|
||||
v,
|
||||
]))
|
||||
// transform full names to short ones: megabits --> mbit, etc.
|
||||
prefixes_array := maps.flat_map[string, string, string](prefixes, |k, v| [k, v])
|
||||
unit = unit.replace_each(prefixes_array)
|
||||
unit = unit.replace_each(['bytes', 'B', 'byte', 'B']).replace_once('bits', 'bit')
|
||||
return unit
|
||||
}
|
||||
@ -355,9 +362,12 @@ fn parse_unit_str(input string, params ParseParams) string {
|
||||
@[params]
|
||||
pub struct ParseParams {
|
||||
pub:
|
||||
ci bool // if true parse string in case insensitive mode
|
||||
bits bool // if true interpret single letter abbreviations as bit, otherwise as byte
|
||||
metric bool // if ture apply single letter as metric prefix (power of ten), otherwise as binary
|
||||
// if true parse string in case insensitive mode
|
||||
case_insensitive bool
|
||||
// if true accept input such 'M', 'Gi' as bits, otherwise as bytes
|
||||
in_bits bool
|
||||
// if true accept single letter prefix as binary (power of two), otherwise as metric prefix
|
||||
binary_size bool
|
||||
}
|
||||
|
||||
// to_string returns a string representation of data size unit in short form
|
||||
|
@ -1,31 +1,39 @@
|
||||
import dataunits
|
||||
|
||||
fn test_convert() {
|
||||
assert (dataunits.nibble * 4).bytes() == 2
|
||||
assert (dataunits.nibble * 4).byte() == 2
|
||||
assert (dataunits.bit * 8).bit() == 8
|
||||
assert (dataunits.bit * 8).bytes() == 1
|
||||
assert (dataunits.bit * 8).byte() == 1
|
||||
assert (dataunits.gib * 10).mib() == 10240
|
||||
assert (dataunits.gib * 5000).bytes() == i64(5368709120000)
|
||||
assert (dataunits.gib * 5000).byte() == 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)
|
||||
assert dataunits.DataSize(4000 * dataunits.gib).byte() == f64(4294967296000)
|
||||
}
|
||||
|
||||
fn test_from_string() {
|
||||
assert dataunits.from_string('GiB')! == dataunits.gib
|
||||
assert dataunits.from_string('M')! == dataunits.mib
|
||||
assert dataunits.from_string('m', ci: true)! == dataunits.mib
|
||||
assert dataunits.from_string('M', bits: true, metric: true)! == dataunits.mbit
|
||||
assert dataunits.from_string('ZeTtAbYtEs', ci: true)! == dataunits.zb
|
||||
assert dataunits.from_string('bytes')! == dataunits.bytes
|
||||
assert dataunits.from_string('byte')! == dataunits.bytes
|
||||
assert dataunits.from_string('M')! == dataunits.mb
|
||||
assert dataunits.from_string('m', case_insensitive: true)! == dataunits.mb
|
||||
assert dataunits.from_string('M', binary_size: true)! == dataunits.mib
|
||||
assert dataunits.from_string('M', in_bits: true)! == dataunits.mbit
|
||||
assert dataunits.from_string('ZeTtAbYtEs', case_insensitive: true)! == dataunits.zb
|
||||
assert dataunits.from_string('bytes')! == dataunits.byte
|
||||
assert dataunits.from_string('byte')! == dataunits.byte
|
||||
assert dataunits.from_string('megabytes')! == dataunits.mb
|
||||
assert dataunits.from_string('megabyte')! == dataunits.mb
|
||||
assert dataunits.from_string('exbibit')! == dataunits.eibit
|
||||
assert dataunits.from_string('Mb')! == dataunits.mbit
|
||||
assert dataunits.from_string('MB')! == dataunits.mb
|
||||
assert dataunits.from_string('Mb', ci: true)! == dataunits.mb
|
||||
assert dataunits.from_string('Mb', case_insensitive: true)! == dataunits.mb
|
||||
assert dataunits.from_string('Gibit')! == dataunits.gibit
|
||||
assert dataunits.from_string('gibit', ci: true)! == dataunits.gibit
|
||||
assert dataunits.from_string('Gib', ci: true)! == dataunits.gib
|
||||
assert dataunits.from_string('gibit', case_insensitive: true)! == dataunits.gibit
|
||||
assert dataunits.from_string('gIBiT', case_insensitive: true)! == dataunits.gibit
|
||||
assert dataunits.from_string('Gib', case_insensitive: true)! == dataunits.gib
|
||||
assert dataunits.from_string('Gib')! == dataunits.gibit
|
||||
assert dataunits.from_string('k')! == dataunits.kb
|
||||
assert dataunits.from_string('kB')! == dataunits.kb
|
||||
assert dataunits.from_string('kb')! == dataunits.kbit
|
||||
assert dataunits.from_string('Ki')! == dataunits.kib
|
||||
assert dataunits.from_string('Gi')! == dataunits.gib
|
||||
}
|
||||
|
Reference in New Issue
Block a user