mirror of
https://github.com/vlang/v.git
synced 2025-09-13 14:32:26 +03:00
all: change optional to result in most of the libraries (#16123)
This commit is contained in:
parent
0d368562f4
commit
51f4d99399
75 changed files with 439 additions and 446 deletions
20
.github/workflows/v_apps_and_modules_compile.yml
vendored
20
.github/workflows/v_apps_and_modules_compile.yml
vendored
|
@ -81,16 +81,16 @@ jobs:
|
||||||
echo "Test libsodium"
|
echo "Test libsodium"
|
||||||
VJOBS=1 v test ~/.vmodules/libsodium
|
VJOBS=1 v test ~/.vmodules/libsodium
|
||||||
|
|
||||||
- name: Build VEX
|
## - name: Build VEX
|
||||||
run: |
|
## run: |
|
||||||
echo "Install Vex"
|
## echo "Install Vex"
|
||||||
v install nedpals.vex
|
## v install nedpals.vex
|
||||||
echo "Compile all of the Vex examples"
|
## echo "Compile all of the Vex examples"
|
||||||
v should-compile-all ~/.vmodules/nedpals/vex/examples
|
## v should-compile-all ~/.vmodules/nedpals/vex/examples
|
||||||
echo "Compile the simple Vex example with -gc boehm -skip-unused"
|
## echo "Compile the simple Vex example with -gc boehm -skip-unused"
|
||||||
v -gc boehm -skip-unused ~/.vmodules/nedpals/vex/examples/simple_example.v
|
## v -gc boehm -skip-unused ~/.vmodules/nedpals/vex/examples/simple_example.v
|
||||||
echo "Run Vex Tests"
|
## echo "Run Vex Tests"
|
||||||
v test ~/.vmodules/nedpals/vex
|
## v test ~/.vmodules/nedpals/vex
|
||||||
|
|
||||||
- name: Build go2v
|
- name: Build go2v
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -16,7 +16,7 @@ fn find_diff_cmd() string {
|
||||||
|
|
||||||
fn test_vet() {
|
fn test_vet() {
|
||||||
os.setenv('VCOLORS', 'never', true)
|
os.setenv('VCOLORS', 'never', true)
|
||||||
os.chdir(vroot)?
|
os.chdir(vroot)!
|
||||||
test_dir := 'cmd/tools/vdoc/tests/testdata'
|
test_dir := 'cmd/tools/vdoc/tests/testdata'
|
||||||
main_files := get_main_files_in_dir(test_dir)
|
main_files := get_main_files_in_dir(test_dir)
|
||||||
fails := check_path(vexe, test_dir, main_files)
|
fails := check_path(vexe, test_dir, main_files)
|
||||||
|
|
|
@ -70,7 +70,7 @@ fn set_output_type_from_str(format string) OutputType {
|
||||||
return output_type
|
return output_type
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_ignore_paths(path string) ?[]string {
|
fn get_ignore_paths(path string) ![]string {
|
||||||
ignore_file_path := os.join_path(path, '.vdocignore')
|
ignore_file_path := os.join_path(path, '.vdocignore')
|
||||||
ignore_content := os.read_file(ignore_file_path) or {
|
ignore_content := os.read_file(ignore_file_path) or {
|
||||||
return error_with_code('ignore file not found.', 1)
|
return error_with_code('ignore file not found.', 1)
|
||||||
|
|
|
@ -41,7 +41,7 @@ fn main() {
|
||||||
cmd.parse(os.args)
|
cmd.parse(os.args)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn greet_func(cmd Command) ? {
|
fn greet_func(cmd Command) ! {
|
||||||
language := cmd.flags.get_string('language') or { panic('Failed to get `language` flag: $err') }
|
language := cmd.flags.get_string('language') or { panic('Failed to get `language` flag: $err') }
|
||||||
times := cmd.flags.get_int('times') or { panic('Failed to get `times` flag: $err') }
|
times := cmd.flags.get_int('times') or { panic('Failed to get `times` flag: $err') }
|
||||||
name := cmd.args[0]
|
name := cmd.args[0]
|
||||||
|
@ -69,10 +69,10 @@ fn greet_func(cmd Command) ? {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn greet_pre_func(cmd Command) ? {
|
fn greet_pre_func(cmd Command) ! {
|
||||||
println('This is a function running before the main function.\n')
|
println('This is a function running before the main function.\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn greet_post_func(cmd Command) ? {
|
fn greet_post_func(cmd Command) ! {
|
||||||
println('\nThis is a function running after the main function.')
|
println('\nThis is a function running after the main function.')
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ fn main() {
|
||||||
for _ in 0 .. repeats {
|
for _ in 0 .. repeats {
|
||||||
mut sb := strings.new_builder(blocksize)
|
mut sb := strings.new_builder(blocksize)
|
||||||
for {
|
for {
|
||||||
x := rand.read(blocksize)?
|
x := rand.read(blocksize)!
|
||||||
for c in x {
|
for c in x {
|
||||||
if c >= `0` && c <= `~` {
|
if c >= `0` && c <= `~` {
|
||||||
sb.write_u8(c)
|
sb.write_u8(c)
|
||||||
|
|
|
@ -9,8 +9,8 @@ import arrays
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
a := [1, 5, 7, 0, 9]
|
a := [1, 5, 7, 0, 9]
|
||||||
assert arrays.min(a)? == 0
|
assert arrays.min(a)! == 0
|
||||||
assert arrays.max(a)? == 9
|
assert arrays.max(a)! == 9
|
||||||
assert arrays.idx_min(a)? == 3
|
assert arrays.idx_min(a)! == 3
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -200,7 +200,7 @@ pub fn window<T>(array []T, attr WindowAttribute) [][]T {
|
||||||
// which means you can only pass array of numbers for now.
|
// which means you can only pass array of numbers for now.
|
||||||
// TODO: Fix generic operator overloading detection issue.
|
// TODO: Fix generic operator overloading detection issue.
|
||||||
// Example: arrays.sum<int>([1, 2, 3, 4, 5])? // => 15
|
// Example: arrays.sum<int>([1, 2, 3, 4, 5])? // => 15
|
||||||
pub fn sum<T>(array []T) ?T {
|
pub fn sum<T>(array []T) !T {
|
||||||
if array.len == 0 {
|
if array.len == 0 {
|
||||||
return error('Cannot sum up array of nothing.')
|
return error('Cannot sum up array of nothing.')
|
||||||
} else {
|
} else {
|
||||||
|
@ -222,8 +222,8 @@ pub fn sum<T>(array []T) ?T {
|
||||||
// returns the accumulated value in `acc`.
|
// returns the accumulated value in `acc`.
|
||||||
// returns an error if the array is empty.
|
// returns an error if the array is empty.
|
||||||
// See also: [fold](#fold).
|
// See also: [fold](#fold).
|
||||||
// Example: arrays.reduce([1, 2, 3, 4, 5], fn (t1 int, t2 int) int { return t1 * t2 })? // => 120
|
// Example: arrays.reduce([1, 2, 3, 4, 5], fn (t1 int, t2 int) int { return t1 * t2 })! // => 120
|
||||||
pub fn reduce<T>(array []T, reduce_op fn (acc T, elem T) T) ?T {
|
pub fn reduce<T>(array []T, reduce_op fn (acc T, elem T) T) !T {
|
||||||
if array.len == 0 {
|
if array.len == 0 {
|
||||||
return error('Cannot reduce array of nothing.')
|
return error('Cannot reduce array of nothing.')
|
||||||
} else {
|
} else {
|
||||||
|
@ -245,7 +245,7 @@ pub fn reduce<T>(array []T, reduce_op fn (acc T, elem T) T) ?T {
|
||||||
// returns the accumulated value in `acc`.
|
// returns the accumulated value in `acc`.
|
||||||
// returns an error if the array is empty.
|
// returns an error if the array is empty.
|
||||||
// See also: [fold_indexed](#fold_indexed).
|
// See also: [fold_indexed](#fold_indexed).
|
||||||
pub fn reduce_indexed<T>(array []T, reduce_op fn (idx int, acc T, elem T) T) ?T {
|
pub fn reduce_indexed<T>(array []T, reduce_op fn (idx int, acc T, elem T) T) !T {
|
||||||
if array.len == 0 {
|
if array.len == 0 {
|
||||||
return error('Cannot reduce array of nothing.')
|
return error('Cannot reduce array of nothing.')
|
||||||
} else {
|
} else {
|
||||||
|
@ -427,8 +427,8 @@ pub fn lower_bound<T>(array []T, val T) !T {
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns the largest element <= val, requires `array` to be sorted
|
// returns the largest element <= val, requires `array` to be sorted
|
||||||
// Example: arrays.upper_bound([2, 4, 6, 8], 3)? // => 2
|
// Example: arrays.upper_bound([2, 4, 6, 8], 3)! // => 2
|
||||||
pub fn upper_bound<T>(array []T, val T) ?T {
|
pub fn upper_bound<T>(array []T, val T) !T {
|
||||||
if array.len == 0 {
|
if array.len == 0 {
|
||||||
return error('.upper_bound called on an empty array')
|
return error('.upper_bound called on an empty array')
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ fn test_min() {
|
||||||
c := [u8(4), 9, 3, 1]
|
c := [u8(4), 9, 3, 1]
|
||||||
mut rb := min(c)!
|
mut rb := min(c)!
|
||||||
assert rb == u8(1)
|
assert rb == u8(1)
|
||||||
rb = min(c[..3])?
|
rb = min(c[..3])!
|
||||||
assert rb == u8(3)
|
assert rb == u8(3)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ fn test_concat_string() {
|
||||||
|
|
||||||
fn test_binary_search() {
|
fn test_binary_search() {
|
||||||
a := [1, 3, 3, 4, 5, 6, 7, 8, 10]
|
a := [1, 3, 3, 4, 5, 6, 7, 8, 10]
|
||||||
assert binary_search(a, 3)? == 1
|
assert binary_search(a, 3)! == 1
|
||||||
assert (binary_search(a, 0) or { -1 }) == -1
|
assert (binary_search(a, 0) or { -1 }) == -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,18 +251,18 @@ fn test_lower_bound() {
|
||||||
a := [1, 3, 3, 4, 5, 6, 7, 8, 10]
|
a := [1, 3, 3, 4, 5, 6, 7, 8, 10]
|
||||||
b := []int{}
|
b := []int{}
|
||||||
c := [1, 2, 3]
|
c := [1, 2, 3]
|
||||||
assert lower_bound(a, 2)? == 3
|
assert lower_bound(a, 2)! == 3
|
||||||
assert (lower_bound(b, 4) or { -1 }) == -1
|
assert (lower_bound(b, 4) or { -1 }) == -1
|
||||||
assert lower_bound(c, 3)? == 3
|
assert lower_bound(c, 3)! == 3
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_upper_bound() {
|
fn test_upper_bound() {
|
||||||
a := [1, 3, 3, 4, 5, 6, 7, 8, 10]
|
a := [1, 3, 3, 4, 5, 6, 7, 8, 10]
|
||||||
b := []int{}
|
b := []int{}
|
||||||
c := [1, 2, 3]
|
c := [1, 2, 3]
|
||||||
assert upper_bound(a, 9)? == 8
|
assert upper_bound(a, 9)! == 8
|
||||||
assert (upper_bound(b, 4) or { -1 }) == -1
|
assert (upper_bound(b, 4) or { -1 }) == -1
|
||||||
assert upper_bound(c, 2)? == 2
|
assert upper_bound(c, 2)! == 2
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_rotate_right() {
|
fn test_rotate_right() {
|
||||||
|
|
|
@ -18,14 +18,14 @@ fn main() {
|
||||||
mut app := cli.Command{
|
mut app := cli.Command{
|
||||||
name: 'example-app'
|
name: 'example-app'
|
||||||
description: 'example-app'
|
description: 'example-app'
|
||||||
execute: fn (cmd cli.Command) ? {
|
execute: fn (cmd cli.Command) ! {
|
||||||
println('hello app')
|
println('hello app')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
commands: [
|
commands: [
|
||||||
cli.Command{
|
cli.Command{
|
||||||
name: 'sub'
|
name: 'sub'
|
||||||
execute: fn (cmd cli.Command) ? {
|
execute: fn (cmd cli.Command) ! {
|
||||||
println('hello subcommand')
|
println('hello subcommand')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ module cli
|
||||||
|
|
||||||
import term
|
import term
|
||||||
|
|
||||||
type FnCommandCallback = fn (cmd Command) ?
|
type FnCommandCallback = fn (cmd Command) !
|
||||||
|
|
||||||
// str returns the `string` representation of the callback.
|
// str returns the `string` representation of the callback.
|
||||||
pub fn (f FnCommandCallback) str() string {
|
pub fn (f FnCommandCallback) str() string {
|
||||||
|
@ -311,7 +311,7 @@ pub fn (cmd Command) execute_man() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (cmds []Command) get(name string) ?Command {
|
fn (cmds []Command) get(name string) !Command {
|
||||||
for cmd in cmds {
|
for cmd in cmds {
|
||||||
if cmd.name == name {
|
if cmd.name == name {
|
||||||
return cmd
|
return cmd
|
||||||
|
|
|
@ -30,7 +30,7 @@ fn test_if_subcommands_parse_args() {
|
||||||
cmd.parse(['command', 'subcommand', 'arg0', 'arg1'])
|
cmd.parse(['command', 'subcommand', 'arg0', 'arg1'])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn if_subcommands_parse_args_func(cmd cli.Command) ? {
|
fn if_subcommands_parse_args_func(cmd cli.Command) ! {
|
||||||
assert cmd.name == 'subcommand' && compare_arrays(cmd.args, ['arg0', 'arg1'])
|
assert cmd.name == 'subcommand' && compare_arrays(cmd.args, ['arg0', 'arg1'])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,8 +51,8 @@ fn test_if_command_has_default_version_subcommand_if_version_is_set() {
|
||||||
assert has_command(cmd, 'version')
|
assert has_command(cmd, 'version')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flag_should_be_set(cmd cli.Command) ? {
|
fn flag_should_be_set(cmd cli.Command) ! {
|
||||||
flag := cmd.flags.get_string('flag')?
|
flag := cmd.flags.get_string('flag')!
|
||||||
assert flag == 'value'
|
assert flag == 'value'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,10 +95,10 @@ fn test_if_flag_gets_set_with_long_arg() {
|
||||||
cmd.parse(['command', '--flag', 'value'])
|
cmd.parse(['command', '--flag', 'value'])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flag_should_have_value_of_42(cmd cli.Command) ? {
|
fn flag_should_have_value_of_42(cmd cli.Command) ! {
|
||||||
flag := cmd.flags.get_string('flag')?
|
flag := cmd.flags.get_string('flag')!
|
||||||
assert flag == 'value'
|
assert flag == 'value'
|
||||||
value := cmd.flags.get_int('value')?
|
value := cmd.flags.get_int('value')!
|
||||||
assert value == 42
|
assert value == 42
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ fn test_if_required_flags_get_set() {
|
||||||
cmd.parse(['command', '-flag', 'value', '-value', '42'])
|
cmd.parse(['command', '-flag', 'value', '-value', '42'])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flag_is_set_in_subcommand(cmd cli.Command) ? {
|
fn flag_is_set_in_subcommand(cmd cli.Command) ! {
|
||||||
flag := cmd.flags.get_string('flag') or { panic(err) }
|
flag := cmd.flags.get_string('flag') or { panic(err) }
|
||||||
assert flag == 'value'
|
assert flag == 'value'
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ fn test_command_setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper functions
|
// helper functions
|
||||||
fn empty_func(cmd cli.Command) ? {
|
fn empty_func(cmd cli.Command) ! {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_command(cmd cli.Command, name string) bool {
|
fn has_command(cmd cli.Command, name string) bool {
|
||||||
|
|
|
@ -42,7 +42,7 @@ pub fn (flags []Flag) get_all_found() []Flag {
|
||||||
|
|
||||||
// get_bool returns `true` if the flag is set.
|
// get_bool returns `true` if the flag is set.
|
||||||
// get_bool returns an error if the `FlagType` is not boolean.
|
// get_bool returns an error if the `FlagType` is not boolean.
|
||||||
pub fn (flag Flag) get_bool() ?bool {
|
pub fn (flag Flag) get_bool() !bool {
|
||||||
if flag.flag != .bool {
|
if flag.flag != .bool {
|
||||||
return error('$flag.name: Invalid flag type `$flag.flag`, expected `bool`')
|
return error('$flag.name: Invalid flag type `$flag.flag`, expected `bool`')
|
||||||
}
|
}
|
||||||
|
@ -54,14 +54,14 @@ pub fn (flag Flag) get_bool() ?bool {
|
||||||
|
|
||||||
// get_bool returns `true` if the flag specified in `name` is set.
|
// get_bool returns `true` if the flag specified in `name` is set.
|
||||||
// get_bool returns an error if the `FlagType` is not boolean.
|
// get_bool returns an error if the `FlagType` is not boolean.
|
||||||
pub fn (flags []Flag) get_bool(name string) ?bool {
|
pub fn (flags []Flag) get_bool(name string) !bool {
|
||||||
flag := flags.get(name)?
|
flag := flags.get(name)!
|
||||||
return flag.get_bool()
|
return flag.get_bool()
|
||||||
}
|
}
|
||||||
|
|
||||||
// get_int returns the `int` value argument of the flag.
|
// get_int returns the `int` value argument of the flag.
|
||||||
// get_int returns an error if the `FlagType` is not integer.
|
// get_int returns an error if the `FlagType` is not integer.
|
||||||
pub fn (flag Flag) get_int() ?int {
|
pub fn (flag Flag) get_int() !int {
|
||||||
if flag.flag != .int {
|
if flag.flag != .int {
|
||||||
return error('$flag.name: Invalid flag type `$flag.flag`, expected `int`')
|
return error('$flag.name: Invalid flag type `$flag.flag`, expected `int`')
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ pub fn (flag Flag) get_int() ?int {
|
||||||
|
|
||||||
// get_ints returns the array of `int` value argument of the flag specified in `name`.
|
// get_ints returns the array of `int` value argument of the flag specified in `name`.
|
||||||
// get_ints returns an error if the `FlagType` is not integer.
|
// get_ints returns an error if the `FlagType` is not integer.
|
||||||
pub fn (flag Flag) get_ints() ?[]int {
|
pub fn (flag Flag) get_ints() ![]int {
|
||||||
if flag.flag != .int_array {
|
if flag.flag != .int_array {
|
||||||
return error('$flag.name: Invalid flag type `$flag.flag`, expected `int_array`')
|
return error('$flag.name: Invalid flag type `$flag.flag`, expected `int_array`')
|
||||||
}
|
}
|
||||||
|
@ -99,21 +99,21 @@ pub fn (flag Flag) get_ints() ?[]int {
|
||||||
|
|
||||||
// get_int returns the `int` value argument of the flag specified in `name`.
|
// get_int returns the `int` value argument of the flag specified in `name`.
|
||||||
// get_int returns an error if the `FlagType` is not integer.
|
// get_int returns an error if the `FlagType` is not integer.
|
||||||
pub fn (flags []Flag) get_int(name string) ?int {
|
pub fn (flags []Flag) get_int(name string) !int {
|
||||||
flag := flags.get(name)?
|
flag := flags.get(name)!
|
||||||
return flag.get_int()
|
return flag.get_int()
|
||||||
}
|
}
|
||||||
|
|
||||||
// get_ints returns the array of `int` value argument of the flag specified in `name`.
|
// get_ints returns the array of `int` value argument of the flag specified in `name`.
|
||||||
// get_ints returns an error if the `FlagType` is not integer.
|
// get_ints returns an error if the `FlagType` is not integer.
|
||||||
pub fn (flags []Flag) get_ints(name string) ?[]int {
|
pub fn (flags []Flag) get_ints(name string) ![]int {
|
||||||
flag := flags.get(name)?
|
flag := flags.get(name)!
|
||||||
return flag.get_ints()
|
return flag.get_ints()
|
||||||
}
|
}
|
||||||
|
|
||||||
// get_float returns the `f64` value argument of the flag.
|
// get_float returns the `f64` value argument of the flag.
|
||||||
// get_float returns an error if the `FlagType` is not floating point.
|
// get_float returns an error if the `FlagType` is not floating point.
|
||||||
pub fn (flag Flag) get_float() ?f64 {
|
pub fn (flag Flag) get_float() !f64 {
|
||||||
if flag.flag != .float {
|
if flag.flag != .float {
|
||||||
return error('$flag.name: Invalid flag type `$flag.flag`, expected `float`')
|
return error('$flag.name: Invalid flag type `$flag.flag`, expected `float`')
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ pub fn (flag Flag) get_float() ?f64 {
|
||||||
|
|
||||||
// get_floats returns the `f64` value argument of the flag.
|
// get_floats returns the `f64` value argument of the flag.
|
||||||
// get_floats returns an error if the `FlagType` is not floating point.
|
// get_floats returns an error if the `FlagType` is not floating point.
|
||||||
pub fn (flag Flag) get_floats() ?[]f64 {
|
pub fn (flag Flag) get_floats() ![]f64 {
|
||||||
if flag.flag != .float_array {
|
if flag.flag != .float_array {
|
||||||
return error('$flag.name: Invalid flag type `$flag.flag`, expected `float_array`')
|
return error('$flag.name: Invalid flag type `$flag.flag`, expected `float_array`')
|
||||||
}
|
}
|
||||||
|
@ -151,21 +151,21 @@ pub fn (flag Flag) get_floats() ?[]f64 {
|
||||||
|
|
||||||
// get_float returns the `f64` value argument of the flag specified in `name`.
|
// get_float returns the `f64` value argument of the flag specified in `name`.
|
||||||
// get_float returns an error if the `FlagType` is not floating point.
|
// get_float returns an error if the `FlagType` is not floating point.
|
||||||
pub fn (flags []Flag) get_float(name string) ?f64 {
|
pub fn (flags []Flag) get_float(name string) !f64 {
|
||||||
flag := flags.get(name)?
|
flag := flags.get(name)!
|
||||||
return flag.get_float()
|
return flag.get_float()
|
||||||
}
|
}
|
||||||
|
|
||||||
// get_floats returns the array of `f64` value argument of the flag specified in `name`.
|
// get_floats returns the array of `f64` value argument of the flag specified in `name`.
|
||||||
// get_floats returns an error if the `FlagType` is not floating point.
|
// get_floats returns an error if the `FlagType` is not floating point.
|
||||||
pub fn (flags []Flag) get_floats(name string) ?[]f64 {
|
pub fn (flags []Flag) get_floats(name string) ![]f64 {
|
||||||
flag := flags.get(name)?
|
flag := flags.get(name)!
|
||||||
return flag.get_floats()
|
return flag.get_floats()
|
||||||
}
|
}
|
||||||
|
|
||||||
// get_string returns the `string` value argument of the flag.
|
// get_string returns the `string` value argument of the flag.
|
||||||
// get_string returns an error if the `FlagType` is not string.
|
// get_string returns an error if the `FlagType` is not string.
|
||||||
pub fn (flag Flag) get_string() ?string {
|
pub fn (flag Flag) get_string() !string {
|
||||||
if flag.flag != .string {
|
if flag.flag != .string {
|
||||||
return error('$flag.name: Invalid flag type `$flag.flag`, expected `string`')
|
return error('$flag.name: Invalid flag type `$flag.flag`, expected `string`')
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,7 @@ pub fn (flag Flag) get_string() ?string {
|
||||||
|
|
||||||
// get_strings returns the array of `string` value argument of the flag.
|
// get_strings returns the array of `string` value argument of the flag.
|
||||||
// get_strings returns an error if the `FlagType` is not string.
|
// get_strings returns an error if the `FlagType` is not string.
|
||||||
pub fn (flag Flag) get_strings() ?[]string {
|
pub fn (flag Flag) get_strings() ![]string {
|
||||||
if flag.flag != .string_array {
|
if flag.flag != .string_array {
|
||||||
return error('$flag.name: Invalid flag type `$flag.flag`, expected `string_array`')
|
return error('$flag.name: Invalid flag type `$flag.flag`, expected `string_array`')
|
||||||
}
|
}
|
||||||
|
@ -197,24 +197,24 @@ pub fn (flag Flag) get_strings() ?[]string {
|
||||||
|
|
||||||
// get_string returns the `string` value argument of the flag specified in `name`.
|
// get_string returns the `string` value argument of the flag specified in `name`.
|
||||||
// get_string returns an error if the `FlagType` is not string.
|
// get_string returns an error if the `FlagType` is not string.
|
||||||
pub fn (flags []Flag) get_string(name string) ?string {
|
pub fn (flags []Flag) get_string(name string) !string {
|
||||||
flag := flags.get(name)?
|
flag := flags.get(name)!
|
||||||
return flag.get_string()
|
return flag.get_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
// get_strings returns the `string` value argument of the flag specified in `name`.
|
// get_strings returns the `string` value argument of the flag specified in `name`.
|
||||||
// get_strings returns an error if the `FlagType` is not string.
|
// get_strings returns an error if the `FlagType` is not string.
|
||||||
pub fn (flags []Flag) get_strings(name string) ?[]string {
|
pub fn (flags []Flag) get_strings(name string) ![]string {
|
||||||
flag := flags.get(name)?
|
flag := flags.get(name)!
|
||||||
return flag.get_strings()
|
return flag.get_strings()
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse parses flag values from arguments and return
|
// parse parses flag values from arguments and return
|
||||||
// an array of arguments with all consumed elements removed.
|
// an array of arguments with all consumed elements removed.
|
||||||
fn (mut flag Flag) parse(args []string, posix_mode bool) ?[]string {
|
fn (mut flag Flag) parse(args []string, posix_mode bool) ![]string {
|
||||||
if flag.matches(args, posix_mode) {
|
if flag.matches(args, posix_mode) {
|
||||||
if flag.flag == .bool {
|
if flag.flag == .bool {
|
||||||
new_args := flag.parse_bool(args)?
|
new_args := flag.parse_bool(args)!
|
||||||
return new_args
|
return new_args
|
||||||
} else {
|
} else {
|
||||||
if flag.value.len > 0 && flag.flag != .int_array && flag.flag != .float_array
|
if flag.value.len > 0 && flag.flag != .int_array && flag.flag != .float_array
|
||||||
|
@ -222,7 +222,7 @@ fn (mut flag Flag) parse(args []string, posix_mode bool) ?[]string {
|
||||||
return error('The argument `$flag.name` accept only one value!')
|
return error('The argument `$flag.name` accept only one value!')
|
||||||
}
|
}
|
||||||
|
|
||||||
new_args := flag.parse_raw(args)?
|
new_args := flag.parse_raw(args)!
|
||||||
return new_args
|
return new_args
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -239,7 +239,7 @@ fn (mut flag Flag) matches(args []string, posix_mode bool) bool {
|
||||||
|| (flag.abbrev != '' && args[0].starts_with('-$flag.abbrev='))
|
|| (flag.abbrev != '' && args[0].starts_with('-$flag.abbrev='))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut flag Flag) parse_raw(args []string) ?[]string {
|
fn (mut flag Flag) parse_raw(args []string) ![]string {
|
||||||
if args[0].len > flag.name.len && args[0].contains('=') {
|
if args[0].len > flag.name.len && args[0].contains('=') {
|
||||||
flag.value << args[0].split('=')[1]
|
flag.value << args[0].split('=')[1]
|
||||||
return args[1..]
|
return args[1..]
|
||||||
|
@ -250,7 +250,7 @@ fn (mut flag Flag) parse_raw(args []string) ?[]string {
|
||||||
return error('Missing argument for `$flag.name`')
|
return error('Missing argument for `$flag.name`')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut flag Flag) parse_bool(args []string) ?[]string {
|
fn (mut flag Flag) parse_bool(args []string) ![]string {
|
||||||
if args[0].len > flag.name.len && args[0].contains('=') {
|
if args[0].len > flag.name.len && args[0].contains('=') {
|
||||||
flag.value = [args[0].split('=')[1]]
|
flag.value = [args[0].split('=')[1]]
|
||||||
return args[1..]
|
return args[1..]
|
||||||
|
@ -267,7 +267,7 @@ fn (mut flag Flag) parse_bool(args []string) ?[]string {
|
||||||
|
|
||||||
// get returns the `Flag` matching `name` or an error
|
// get returns the `Flag` matching `name` or an error
|
||||||
// if it can't be found.
|
// if it can't be found.
|
||||||
fn (flags []Flag) get(name string) ?Flag {
|
fn (flags []Flag) get(name string) !Flag {
|
||||||
for flag in flags {
|
for flag in flags {
|
||||||
if flag.name == name {
|
if flag.name == name {
|
||||||
return flag
|
return flag
|
||||||
|
|
|
@ -29,7 +29,7 @@ fn help_cmd() Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
// print_help_for_command outputs the help message of `help_cmd`.
|
// print_help_for_command outputs the help message of `help_cmd`.
|
||||||
pub fn print_help_for_command(help_cmd Command) ? {
|
pub fn print_help_for_command(help_cmd Command) ! {
|
||||||
if help_cmd.args.len > 0 {
|
if help_cmd.args.len > 0 {
|
||||||
mut cmd := help_cmd.parent
|
mut cmd := help_cmd.parent
|
||||||
for arg in help_cmd.args {
|
for arg in help_cmd.args {
|
||||||
|
|
|
@ -21,7 +21,7 @@ fn man_cmd() Command {
|
||||||
|
|
||||||
// print_manpage_for_command prints the manpage for the
|
// print_manpage_for_command prints the manpage for the
|
||||||
// command or subcommand in `man_cmd` to stdout
|
// command or subcommand in `man_cmd` to stdout
|
||||||
pub fn print_manpage_for_command(man_cmd Command) ? {
|
pub fn print_manpage_for_command(man_cmd Command) ! {
|
||||||
if man_cmd.args.len > 0 {
|
if man_cmd.args.len > 0 {
|
||||||
mut cmd := man_cmd.parent
|
mut cmd := man_cmd.parent
|
||||||
for arg in man_cmd.args {
|
for arg in man_cmd.args {
|
||||||
|
|
|
@ -18,7 +18,7 @@ fn version_cmd() Command {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn version_func(version_cmd Command) ? {
|
fn version_func(version_cmd Command) ! {
|
||||||
cmd := version_cmd.parent
|
cmd := version_cmd.parent
|
||||||
version := '$cmd.name version $cmd.version'
|
version := '$cmd.name version $cmd.version'
|
||||||
println(version)
|
println(version)
|
||||||
|
|
|
@ -11,7 +11,7 @@ fn C.tinfl_decompress_mem_to_heap(source_buf voidptr, source_buf_len usize, out_
|
||||||
// compresses an array of bytes based on providing flags and returns the compressed bytes in a new array
|
// compresses an array of bytes based on providing flags and returns the compressed bytes in a new array
|
||||||
// NB: this is a low level api, a high level implementation like zlib/gzip should be preferred
|
// NB: this is a low level api, a high level implementation like zlib/gzip should be preferred
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn compress(data []u8, flags int) ?[]u8 {
|
pub fn compress(data []u8, flags int) ![]u8 {
|
||||||
if u64(data.len) > compress.max_size {
|
if u64(data.len) > compress.max_size {
|
||||||
return error('data too large ($data.len > $compress.max_size)')
|
return error('data too large ($data.len > $compress.max_size)')
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ pub fn compress(data []u8, flags int) ?[]u8 {
|
||||||
// decompresses an array of bytes based on providing flags and returns the decompressed bytes in a new array
|
// decompresses an array of bytes based on providing flags and returns the decompressed bytes in a new array
|
||||||
// NB: this is a low level api, a high level implementation like zlib/gzip should be preferred
|
// NB: this is a low level api, a high level implementation like zlib/gzip should be preferred
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn decompress(data []u8, flags int) ?[]u8 {
|
pub fn decompress(data []u8, flags int) ![]u8 {
|
||||||
mut out_len := usize(0)
|
mut out_len := usize(0)
|
||||||
|
|
||||||
address := C.tinfl_decompress_mem_to_heap(data.data, data.len, &out_len, flags)
|
address := C.tinfl_decompress_mem_to_heap(data.data, data.len, &out_len, flags)
|
||||||
|
|
|
@ -11,8 +11,8 @@ import compress.deflate
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
uncompressed := 'Hello world!'
|
uncompressed := 'Hello world!'
|
||||||
compressed := deflate.compress(uncompressed.bytes())?
|
compressed := deflate.compress(uncompressed.bytes())!
|
||||||
decompressed := deflate.decompress(compressed)?
|
decompressed := deflate.decompress(compressed)!
|
||||||
assert decompressed == uncompressed.bytes()
|
assert decompressed == uncompressed.bytes()
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -4,12 +4,12 @@ import compress
|
||||||
|
|
||||||
// compresses an array of bytes using deflate and returns the compressed bytes in a new array
|
// compresses an array of bytes using deflate and returns the compressed bytes in a new array
|
||||||
// Example: compressed := deflate.compress(b)?
|
// Example: compressed := deflate.compress(b)?
|
||||||
pub fn compress(data []u8) ?[]u8 {
|
pub fn compress(data []u8) ![]u8 {
|
||||||
return compress.compress(data, 0)
|
return compress.compress(data, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// decompresses an array of bytes using deflate and returns the decompressed bytes in a new array
|
// decompresses an array of bytes using deflate and returns the decompressed bytes in a new array
|
||||||
// Example: decompressed := deflate.decompress(b)?
|
// Example: decompressed := deflate.decompress(b)?
|
||||||
pub fn decompress(data []u8) ?[]u8 {
|
pub fn decompress(data []u8) ![]u8 {
|
||||||
return compress.decompress(data, 0)
|
return compress.decompress(data, 0)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,11 @@ module deflate
|
||||||
|
|
||||||
const gzip_magic_numbers = [u8(0x1f), 0x8b]
|
const gzip_magic_numbers = [u8(0x1f), 0x8b]
|
||||||
|
|
||||||
fn test_gzip() ? {
|
fn test_gzip() {
|
||||||
uncompressed := 'Hello world!'
|
uncompressed := 'Hello world!'
|
||||||
compressed := compress(uncompressed.bytes())?
|
compressed := compress(uncompressed.bytes())!
|
||||||
first2 := compressed[0..2]
|
first2 := compressed[0..2]
|
||||||
assert first2 != deflate.gzip_magic_numbers
|
assert first2 != deflate.gzip_magic_numbers
|
||||||
decompressed := decompress(compressed)?
|
decompressed := decompress(compressed)!
|
||||||
assert decompressed == uncompressed.bytes()
|
assert decompressed == uncompressed.bytes()
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@ import compress.gzip
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
uncompressed := 'Hello world!'
|
uncompressed := 'Hello world!'
|
||||||
compressed := gzip.compress(uncompressed.bytes())?
|
compressed := gzip.compress(uncompressed.bytes())!
|
||||||
decompressed := gzip.decompress(compressed)?
|
decompressed := gzip.decompress(compressed)!
|
||||||
assert decompressed == uncompressed.bytes()
|
assert decompressed == uncompressed.bytes()
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -8,8 +8,8 @@ import hash.crc32
|
||||||
|
|
||||||
// compresses an array of bytes using gzip and returns the compressed bytes in a new array
|
// compresses an array of bytes using gzip and returns the compressed bytes in a new array
|
||||||
// Example: compressed := gzip.compress(b)?
|
// Example: compressed := gzip.compress(b)?
|
||||||
pub fn compress(data []u8) ?[]u8 {
|
pub fn compress(data []u8) ![]u8 {
|
||||||
compressed := compress.compress(data, 0)?
|
compressed := compress.compress(data, 0)!
|
||||||
// header
|
// header
|
||||||
mut result := [
|
mut result := [
|
||||||
u8(0x1f), // magic numbers (1F 8B)
|
u8(0x1f), // magic numbers (1F 8B)
|
||||||
|
@ -49,7 +49,7 @@ pub struct DecompressParams {
|
||||||
|
|
||||||
// decompresses an array of bytes using zlib and returns the decompressed bytes in a new array
|
// decompresses an array of bytes using zlib and returns the decompressed bytes in a new array
|
||||||
// Example: decompressed := gzip.decompress(b)?
|
// Example: decompressed := gzip.decompress(b)?
|
||||||
pub fn decompress(data []u8, params DecompressParams) ?[]u8 {
|
pub fn decompress(data []u8, params DecompressParams) ![]u8 {
|
||||||
if data.len < 18 {
|
if data.len < 18 {
|
||||||
return error('data is too short, not gzip compressed?')
|
return error('data is too short, not gzip compressed?')
|
||||||
} else if data[0] != 0x1f || data[1] != 0x8b {
|
} else if data[0] != 0x1f || data[1] != 0x8b {
|
||||||
|
@ -107,7 +107,7 @@ pub fn decompress(data []u8, params DecompressParams) ?[]u8 {
|
||||||
return error('data too short')
|
return error('data too short')
|
||||||
}
|
}
|
||||||
|
|
||||||
decompressed := compress.decompress(data[header_length..data.len - 8], 0)?
|
decompressed := compress.decompress(data[header_length..data.len - 8], 0)!
|
||||||
length_expected := (u32(data[data.len - 4]) << 24) | (u32(data[data.len - 3]) << 16) | (u32(data[data.len - 2]) << 8) | data[data.len - 1]
|
length_expected := (u32(data[data.len - 4]) << 24) | (u32(data[data.len - 3]) << 16) | (u32(data[data.len - 2]) << 8) | data[data.len - 1]
|
||||||
if params.verify_length && decompressed.len != length_expected {
|
if params.verify_length && decompressed.len != length_expected {
|
||||||
return error('length verification failed, got $decompressed.len, expected $length_expected')
|
return error('length verification failed, got $decompressed.len, expected $length_expected')
|
||||||
|
|
|
@ -2,14 +2,14 @@ module gzip
|
||||||
|
|
||||||
import hash.crc32
|
import hash.crc32
|
||||||
|
|
||||||
fn test_gzip() ? {
|
fn test_gzip() {
|
||||||
uncompressed := 'Hello world!'
|
uncompressed := 'Hello world!'
|
||||||
compressed := compress(uncompressed.bytes())?
|
compressed := compress(uncompressed.bytes())!
|
||||||
decompressed := decompress(compressed)?
|
decompressed := decompress(compressed)!
|
||||||
assert decompressed == uncompressed.bytes()
|
assert decompressed == uncompressed.bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_decompress_error(data []u8, reason string) ? {
|
fn assert_decompress_error(data []u8, reason string) ! {
|
||||||
decompress(data) or {
|
decompress(data) or {
|
||||||
assert err.msg() == reason
|
assert err.msg() == reason
|
||||||
return
|
return
|
||||||
|
@ -17,54 +17,54 @@ fn assert_decompress_error(data []u8, reason string) ? {
|
||||||
return error('did not error')
|
return error('did not error')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_gzip_invalid_too_short() ? {
|
fn test_gzip_invalid_too_short() {
|
||||||
assert_decompress_error([]u8{}, 'data is too short, not gzip compressed?')?
|
assert_decompress_error([]u8{}, 'data is too short, not gzip compressed?')!
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_gzip_invalid_magic_numbers() ? {
|
fn test_gzip_invalid_magic_numbers() {
|
||||||
assert_decompress_error([]u8{len: 100}, 'wrong magic numbers, not gzip compressed?')?
|
assert_decompress_error([]u8{len: 100}, 'wrong magic numbers, not gzip compressed?')!
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_gzip_invalid_compression() ? {
|
fn test_gzip_invalid_compression() {
|
||||||
mut data := []u8{len: 100}
|
mut data := []u8{len: 100}
|
||||||
data[0] = 0x1f
|
data[0] = 0x1f
|
||||||
data[1] = 0x8b
|
data[1] = 0x8b
|
||||||
assert_decompress_error(data, 'gzip data is not compressed with DEFLATE')?
|
assert_decompress_error(data, 'gzip data is not compressed with DEFLATE')!
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_gzip_with_ftext() ? {
|
fn test_gzip_with_ftext() {
|
||||||
uncompressed := 'Hello world!'
|
uncompressed := 'Hello world!'
|
||||||
mut compressed := compress(uncompressed.bytes())?
|
mut compressed := compress(uncompressed.bytes())!
|
||||||
compressed[4] |= 0b0000_0001 // FTEXT
|
compressed[4] |= 0b0000_0001 // FTEXT
|
||||||
decompressed := decompress(compressed)?
|
decompressed := decompress(compressed)!
|
||||||
assert decompressed == uncompressed.bytes()
|
assert decompressed == uncompressed.bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_gzip_with_fname() ? {
|
fn test_gzip_with_fname() {
|
||||||
uncompressed := 'Hello world!'
|
uncompressed := 'Hello world!'
|
||||||
mut compressed := compress(uncompressed.bytes())?
|
mut compressed := compress(uncompressed.bytes())!
|
||||||
compressed[4] |= 0b0000_1000
|
compressed[4] |= 0b0000_1000
|
||||||
compressed.insert(10, `h`)
|
compressed.insert(10, `h`)
|
||||||
compressed.insert(11, `i`)
|
compressed.insert(11, `i`)
|
||||||
compressed.insert(12, 0x00)
|
compressed.insert(12, 0x00)
|
||||||
decompressed := decompress(compressed)?
|
decompressed := decompress(compressed)!
|
||||||
assert decompressed == uncompressed.bytes()
|
assert decompressed == uncompressed.bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_gzip_with_fcomment() ? {
|
fn test_gzip_with_fcomment() {
|
||||||
uncompressed := 'Hello world!'
|
uncompressed := 'Hello world!'
|
||||||
mut compressed := compress(uncompressed.bytes())?
|
mut compressed := compress(uncompressed.bytes())!
|
||||||
compressed[4] |= 0b0001_0000
|
compressed[4] |= 0b0001_0000
|
||||||
compressed.insert(10, `h`)
|
compressed.insert(10, `h`)
|
||||||
compressed.insert(11, `i`)
|
compressed.insert(11, `i`)
|
||||||
compressed.insert(12, 0x00)
|
compressed.insert(12, 0x00)
|
||||||
decompressed := decompress(compressed)?
|
decompressed := decompress(compressed)!
|
||||||
assert decompressed == uncompressed.bytes()
|
assert decompressed == uncompressed.bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_gzip_with_fname_fcomment() ? {
|
fn test_gzip_with_fname_fcomment() {
|
||||||
uncompressed := 'Hello world!'
|
uncompressed := 'Hello world!'
|
||||||
mut compressed := compress(uncompressed.bytes())?
|
mut compressed := compress(uncompressed.bytes())!
|
||||||
compressed[4] |= 0b0001_1000
|
compressed[4] |= 0b0001_1000
|
||||||
compressed.insert(10, `h`)
|
compressed.insert(10, `h`)
|
||||||
compressed.insert(11, `i`)
|
compressed.insert(11, `i`)
|
||||||
|
@ -72,63 +72,63 @@ fn test_gzip_with_fname_fcomment() ? {
|
||||||
compressed.insert(10, `h`)
|
compressed.insert(10, `h`)
|
||||||
compressed.insert(11, `i`)
|
compressed.insert(11, `i`)
|
||||||
compressed.insert(12, 0x00)
|
compressed.insert(12, 0x00)
|
||||||
decompressed := decompress(compressed)?
|
decompressed := decompress(compressed)!
|
||||||
assert decompressed == uncompressed.bytes()
|
assert decompressed == uncompressed.bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_gzip_with_fextra() ? {
|
fn test_gzip_with_fextra() {
|
||||||
uncompressed := 'Hello world!'
|
uncompressed := 'Hello world!'
|
||||||
mut compressed := compress(uncompressed.bytes())?
|
mut compressed := compress(uncompressed.bytes())!
|
||||||
compressed[4] |= 0b0000_0100
|
compressed[4] |= 0b0000_0100
|
||||||
compressed.insert(10, 2)
|
compressed.insert(10, 2)
|
||||||
compressed.insert(11, `h`)
|
compressed.insert(11, `h`)
|
||||||
compressed.insert(12, `i`)
|
compressed.insert(12, `i`)
|
||||||
decompressed := decompress(compressed)?
|
decompressed := decompress(compressed)!
|
||||||
assert decompressed == uncompressed.bytes()
|
assert decompressed == uncompressed.bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_gzip_with_hcrc() ? {
|
fn test_gzip_with_hcrc() {
|
||||||
uncompressed := 'Hello world!'
|
uncompressed := 'Hello world!'
|
||||||
mut compressed := compress(uncompressed.bytes())?
|
mut compressed := compress(uncompressed.bytes())!
|
||||||
compressed[4] |= 0b0000_0010
|
compressed[4] |= 0b0000_0010
|
||||||
checksum := crc32.sum(compressed[..10])
|
checksum := crc32.sum(compressed[..10])
|
||||||
compressed.insert(10, u8(checksum >> 24))
|
compressed.insert(10, u8(checksum >> 24))
|
||||||
compressed.insert(11, u8(checksum >> 16))
|
compressed.insert(11, u8(checksum >> 16))
|
||||||
compressed.insert(12, u8(checksum >> 8))
|
compressed.insert(12, u8(checksum >> 8))
|
||||||
compressed.insert(13, u8(checksum))
|
compressed.insert(13, u8(checksum))
|
||||||
decompressed := decompress(compressed)?
|
decompressed := decompress(compressed)!
|
||||||
assert decompressed == uncompressed.bytes()
|
assert decompressed == uncompressed.bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_gzip_with_invalid_hcrc() ? {
|
fn test_gzip_with_invalid_hcrc() {
|
||||||
uncompressed := 'Hello world!'
|
uncompressed := 'Hello world!'
|
||||||
mut compressed := compress(uncompressed.bytes())?
|
mut compressed := compress(uncompressed.bytes())!
|
||||||
compressed[4] |= 0b0000_0010
|
compressed[4] |= 0b0000_0010
|
||||||
checksum := crc32.sum(compressed[..10])
|
checksum := crc32.sum(compressed[..10])
|
||||||
compressed.insert(10, u8(checksum >> 24))
|
compressed.insert(10, u8(checksum >> 24))
|
||||||
compressed.insert(11, u8(checksum >> 16))
|
compressed.insert(11, u8(checksum >> 16))
|
||||||
compressed.insert(12, u8(checksum >> 8))
|
compressed.insert(12, u8(checksum >> 8))
|
||||||
compressed.insert(13, u8(checksum + 1))
|
compressed.insert(13, u8(checksum + 1))
|
||||||
assert_decompress_error(compressed, 'header checksum verification failed')?
|
assert_decompress_error(compressed, 'header checksum verification failed')!
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_gzip_with_invalid_checksum() ? {
|
fn test_gzip_with_invalid_checksum() {
|
||||||
uncompressed := 'Hello world!'
|
uncompressed := 'Hello world!'
|
||||||
mut compressed := compress(uncompressed.bytes())?
|
mut compressed := compress(uncompressed.bytes())!
|
||||||
compressed[compressed.len - 5] += 1
|
compressed[compressed.len - 5] += 1
|
||||||
assert_decompress_error(compressed, 'checksum verification failed')?
|
assert_decompress_error(compressed, 'checksum verification failed')!
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_gzip_with_invalid_length() ? {
|
fn test_gzip_with_invalid_length() {
|
||||||
uncompressed := 'Hello world!'
|
uncompressed := 'Hello world!'
|
||||||
mut compressed := compress(uncompressed.bytes())?
|
mut compressed := compress(uncompressed.bytes())!
|
||||||
compressed[compressed.len - 1] += 1
|
compressed[compressed.len - 1] += 1
|
||||||
assert_decompress_error(compressed, 'length verification failed, got 12, expected 13')?
|
assert_decompress_error(compressed, 'length verification failed, got 12, expected 13')!
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_gzip_with_invalid_flags() ? {
|
fn test_gzip_with_invalid_flags() {
|
||||||
uncompressed := 'Hello world!'
|
uncompressed := 'Hello world!'
|
||||||
mut compressed := compress(uncompressed.bytes())?
|
mut compressed := compress(uncompressed.bytes())!
|
||||||
compressed[4] |= 0b1000_0000
|
compressed[4] |= 0b1000_0000
|
||||||
assert_decompress_error(compressed, 'reserved flags are set, unsupported field detected')?
|
assert_decompress_error(compressed, 'reserved flags are set, unsupported field detected')!
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,8 @@ import compress.zlib
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
uncompressed := 'Hello world!'
|
uncompressed := 'Hello world!'
|
||||||
compressed := zlib.compress(uncompressed.bytes())?
|
compressed := zlib.compress(uncompressed.bytes())!
|
||||||
decompressed := zlib.decompress(compressed)?
|
decompressed := zlib.decompress(compressed)!
|
||||||
assert decompressed == uncompressed.bytes()
|
assert decompressed == uncompressed.bytes()
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -4,14 +4,14 @@ import compress
|
||||||
|
|
||||||
// compresses an array of bytes using zlib and returns the compressed bytes in a new array
|
// compresses an array of bytes using zlib and returns the compressed bytes in a new array
|
||||||
// Example: compressed := zlib.compress(b)?
|
// Example: compressed := zlib.compress(b)?
|
||||||
pub fn compress(data []u8) ?[]u8 {
|
pub fn compress(data []u8) ![]u8 {
|
||||||
// flags = TDEFL_WRITE_ZLIB_HEADER (0x01000)
|
// flags = TDEFL_WRITE_ZLIB_HEADER (0x01000)
|
||||||
return compress.compress(data, 0x01000)
|
return compress.compress(data, 0x01000)
|
||||||
}
|
}
|
||||||
|
|
||||||
// decompresses an array of bytes using zlib and returns the decompressed bytes in a new array
|
// decompresses an array of bytes using zlib and returns the decompressed bytes in a new array
|
||||||
// Example: decompressed := zlib.decompress(b)?
|
// Example: decompressed := zlib.decompress(b)?
|
||||||
pub fn decompress(data []u8) ?[]u8 {
|
pub fn decompress(data []u8) ![]u8 {
|
||||||
// flags = TINFL_FLAG_PARSE_ZLIB_HEADER (0x1)
|
// flags = TINFL_FLAG_PARSE_ZLIB_HEADER (0x1)
|
||||||
return compress.decompress(data, 0x1)
|
return compress.decompress(data, 0x1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
module zlib
|
module zlib
|
||||||
|
|
||||||
fn test_zlib() ? {
|
fn test_zlib() {
|
||||||
uncompressed := 'Hello world!'
|
uncompressed := 'Hello world!'
|
||||||
compressed := compress(uncompressed.bytes())?
|
compressed := compress(uncompressed.bytes())!
|
||||||
decompressed := decompress(compressed)?
|
decompressed := decompress(compressed)!
|
||||||
assert decompressed == uncompressed.bytes()
|
assert decompressed == uncompressed.bytes()
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import crypto.rand
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// remember to save this key somewhere if you ever want to decrypt your data
|
// remember to save this key somewhere if you ever want to decrypt your data
|
||||||
key := rand.bytes(32)?
|
key := rand.bytes(32)!
|
||||||
println('KEY: $key')
|
println('KEY: $key')
|
||||||
|
|
||||||
// this data is one block (16 bytes) big
|
// this data is one block (16 bytes) big
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub fn (priv PrivateKey) equal(x []u8) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// sign signs the given message with priv.
|
// sign signs the given message with priv.
|
||||||
pub fn (priv PrivateKey) sign(message []u8) ?[]u8 {
|
pub fn (priv PrivateKey) sign(message []u8) ![]u8 {
|
||||||
/*
|
/*
|
||||||
if opts.HashFunc() != crypto.Hash(0) {
|
if opts.HashFunc() != crypto.Hash(0) {
|
||||||
return nil, errors.New("ed25519: cannot sign hashed message")
|
return nil, errors.New("ed25519: cannot sign hashed message")
|
||||||
|
@ -60,13 +60,13 @@ pub fn (priv PrivateKey) sign(message []u8) ?[]u8 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// sign`signs the message with privatekey and returns a signature
|
// sign`signs the message with privatekey and returns a signature
|
||||||
pub fn sign(privatekey PrivateKey, message []u8) ?[]u8 {
|
pub fn sign(privatekey PrivateKey, message []u8) ![]u8 {
|
||||||
mut signature := []u8{len: ed25519.signature_size}
|
mut signature := []u8{len: ed25519.signature_size}
|
||||||
sign_generic(mut signature, privatekey, message)?
|
sign_generic(mut signature, privatekey, message)!
|
||||||
return signature
|
return signature
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_generic(mut signature []u8, privatekey []u8, message []u8) ? {
|
fn sign_generic(mut signature []u8, privatekey []u8, message []u8) ! {
|
||||||
if privatekey.len != ed25519.private_key_size {
|
if privatekey.len != ed25519.private_key_size {
|
||||||
panic('ed25519: bad private key length: $privatekey.len')
|
panic('ed25519: bad private key length: $privatekey.len')
|
||||||
}
|
}
|
||||||
|
@ -74,31 +74,31 @@ fn sign_generic(mut signature []u8, privatekey []u8, message []u8) ? {
|
||||||
|
|
||||||
mut h := sha512.sum512(seed)
|
mut h := sha512.sum512(seed)
|
||||||
mut s := edwards25519.new_scalar()
|
mut s := edwards25519.new_scalar()
|
||||||
s.set_bytes_with_clamping(h[..32])?
|
s.set_bytes_with_clamping(h[..32])!
|
||||||
mut prefix := h[32..]
|
mut prefix := h[32..]
|
||||||
|
|
||||||
mut mh := sha512.new()
|
mut mh := sha512.new()
|
||||||
mh.write(prefix)?
|
mh.write(prefix)!
|
||||||
mh.write(message)?
|
mh.write(message)!
|
||||||
|
|
||||||
mut msg_digest := []u8{cap: sha512.size}
|
mut msg_digest := []u8{cap: sha512.size}
|
||||||
msg_digest = mh.sum(msg_digest)
|
msg_digest = mh.sum(msg_digest)
|
||||||
|
|
||||||
mut r := edwards25519.new_scalar()
|
mut r := edwards25519.new_scalar()
|
||||||
r.set_uniform_bytes(msg_digest)?
|
r.set_uniform_bytes(msg_digest)!
|
||||||
|
|
||||||
mut rr := edwards25519.Point{}
|
mut rr := edwards25519.Point{}
|
||||||
rr.scalar_base_mult(mut r)
|
rr.scalar_base_mult(mut r)
|
||||||
|
|
||||||
mut kh := sha512.new()
|
mut kh := sha512.new()
|
||||||
kh.write(rr.bytes())?
|
kh.write(rr.bytes())!
|
||||||
kh.write(publickey)?
|
kh.write(publickey)!
|
||||||
kh.write(message)?
|
kh.write(message)!
|
||||||
|
|
||||||
mut hram_digest := []u8{cap: sha512.size}
|
mut hram_digest := []u8{cap: sha512.size}
|
||||||
hram_digest = kh.sum(hram_digest)
|
hram_digest = kh.sum(hram_digest)
|
||||||
mut k := edwards25519.new_scalar()
|
mut k := edwards25519.new_scalar()
|
||||||
k.set_uniform_bytes(hram_digest)?
|
k.set_uniform_bytes(hram_digest)!
|
||||||
|
|
||||||
mut ss := edwards25519.new_scalar()
|
mut ss := edwards25519.new_scalar()
|
||||||
ss.multiply_add(k, s, r)
|
ss.multiply_add(k, s, r)
|
||||||
|
@ -108,7 +108,7 @@ fn sign_generic(mut signature []u8, privatekey []u8, message []u8) ? {
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify reports whether sig is a valid signature of message by publickey.
|
// verify reports whether sig is a valid signature of message by publickey.
|
||||||
pub fn verify(publickey PublicKey, message []u8, sig []u8) ?bool {
|
pub fn verify(publickey PublicKey, message []u8, sig []u8) !bool {
|
||||||
if publickey.len != ed25519.public_key_size {
|
if publickey.len != ed25519.public_key_size {
|
||||||
return error('ed25519: bad public key length: $publickey.len')
|
return error('ed25519: bad public key length: $publickey.len')
|
||||||
}
|
}
|
||||||
|
@ -118,21 +118,21 @@ pub fn verify(publickey PublicKey, message []u8, sig []u8) ?bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
mut aa := edwards25519.Point{}
|
mut aa := edwards25519.Point{}
|
||||||
aa.set_bytes(publickey)?
|
aa.set_bytes(publickey)!
|
||||||
|
|
||||||
mut kh := sha512.new()
|
mut kh := sha512.new()
|
||||||
kh.write(sig[..32])?
|
kh.write(sig[..32])!
|
||||||
kh.write(publickey)?
|
kh.write(publickey)!
|
||||||
kh.write(message)?
|
kh.write(message)!
|
||||||
|
|
||||||
mut hram_digest := []u8{cap: sha512.size}
|
mut hram_digest := []u8{cap: sha512.size}
|
||||||
hram_digest = kh.sum(hram_digest)
|
hram_digest = kh.sum(hram_digest)
|
||||||
|
|
||||||
mut k := edwards25519.new_scalar()
|
mut k := edwards25519.new_scalar()
|
||||||
k.set_uniform_bytes(hram_digest)?
|
k.set_uniform_bytes(hram_digest)!
|
||||||
|
|
||||||
mut ss := edwards25519.new_scalar()
|
mut ss := edwards25519.new_scalar()
|
||||||
ss.set_canonical_bytes(sig[32..])?
|
ss.set_canonical_bytes(sig[32..])!
|
||||||
|
|
||||||
// [S]B = R + [k]A --> [k](-A) + [S]B = R
|
// [S]B = R + [k]A --> [k](-A) + [S]B = R
|
||||||
mut minus_a := edwards25519.Point{}
|
mut minus_a := edwards25519.Point{}
|
||||||
|
@ -144,8 +144,8 @@ pub fn verify(publickey PublicKey, message []u8, sig []u8) ?bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate_key generates a public/private key pair entropy using `crypto.rand`.
|
// generate_key generates a public/private key pair entropy using `crypto.rand`.
|
||||||
pub fn generate_key() ?(PublicKey, PrivateKey) {
|
pub fn generate_key() !(PublicKey, PrivateKey) {
|
||||||
mut seed := rand.bytes(ed25519.seed_size)?
|
mut seed := rand.bytes(ed25519.seed_size)!
|
||||||
|
|
||||||
privatekey := new_key_from_seed(seed)
|
privatekey := new_key_from_seed(seed)
|
||||||
mut publickey := []u8{len: ed25519.public_key_size}
|
mut publickey := []u8{len: ed25519.public_key_size}
|
||||||
|
|
|
@ -8,11 +8,11 @@ import crypto.ed25519
|
||||||
fn main() {
|
fn main() {
|
||||||
msg := 'Hello Girl'
|
msg := 'Hello Girl'
|
||||||
|
|
||||||
publ, priv := ed25519.generate_key()?
|
publ, priv := ed25519.generate_key()!
|
||||||
|
|
||||||
m := msg.bytes()
|
m := msg.bytes()
|
||||||
|
|
||||||
sig := ed25519.sign(priv, m)?
|
sig := ed25519.sign(priv, m)!
|
||||||
|
|
||||||
println('=== Message ===')
|
println('=== Message ===')
|
||||||
println('Msg: $msg \nHash: $m')
|
println('Msg: $msg \nHash: $m')
|
||||||
|
@ -31,7 +31,7 @@ fn main() {
|
||||||
println('signature: R=${sig[0..32].hex()} s=${sig[32..64].hex()}')
|
println('signature: R=${sig[0..32].hex()} s=${sig[32..64].hex()}')
|
||||||
println(' signature (Base64)=${base64.encode(sig)}')
|
println(' signature (Base64)=${base64.encode(sig)}')
|
||||||
|
|
||||||
rtn := ed25519.verify(publ, m, sig)?
|
rtn := ed25519.verify(publ, m, sig)!
|
||||||
|
|
||||||
if rtn {
|
if rtn {
|
||||||
println('Signature verified :$rtn')
|
println('Signature verified :$rtn')
|
||||||
|
|
|
@ -27,22 +27,22 @@ fn (z ZeroReader) read(mut buf []u8) ?int {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fn test_sign_verify() ? {
|
fn test_sign_verify() {
|
||||||
// mut zero := ZeroReader{}
|
// mut zero := ZeroReader{}
|
||||||
public, private := ed25519.generate_key()?
|
public, private := ed25519.generate_key()!
|
||||||
|
|
||||||
message := 'test message'.bytes()
|
message := 'test message'.bytes()
|
||||||
sig := ed25519.sign(private, message)?
|
sig := ed25519.sign(private, message)!
|
||||||
res := ed25519.verify(public, message, sig) or { false }
|
res := ed25519.verify(public, message, sig) or { false }
|
||||||
assert res == true
|
assert res == true
|
||||||
|
|
||||||
wrongmessage := 'wrong message'.bytes()
|
wrongmessage := 'wrong message'.bytes()
|
||||||
res2 := ed25519.verify(public, wrongmessage, sig)?
|
res2 := ed25519.verify(public, wrongmessage, sig)!
|
||||||
assert res2 == false
|
assert res2 == false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_equal() ? {
|
fn test_equal() {
|
||||||
public, private := ed25519.generate_key()?
|
public, private := ed25519.generate_key()!
|
||||||
|
|
||||||
assert public.equal(public) == true
|
assert public.equal(public) == true
|
||||||
|
|
||||||
|
@ -53,13 +53,13 @@ fn test_equal() ? {
|
||||||
}*/
|
}*/
|
||||||
assert private.equal(private) == true
|
assert private.equal(private) == true
|
||||||
|
|
||||||
otherpub, otherpriv := ed25519.generate_key()?
|
otherpub, otherpriv := ed25519.generate_key()!
|
||||||
assert public.equal(otherpub) == false
|
assert public.equal(otherpub) == false
|
||||||
|
|
||||||
assert private.equal(otherpriv) == false
|
assert private.equal(otherpriv) == false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_malleability() ? {
|
fn test_malleability() {
|
||||||
// https://tools.ietf.org/html/rfc8032#section-5.1.7 adds an additional test
|
// https://tools.ietf.org/html/rfc8032#section-5.1.7 adds an additional test
|
||||||
// that s be in [0, order). This prevents someone from adding a multiple of
|
// that s be in [0, order). This prevents someone from adding a multiple of
|
||||||
// order to s and obtaining a second valid signature for the same message.
|
// order to s and obtaining a second valid signature for the same message.
|
||||||
|
@ -149,7 +149,7 @@ mut:
|
||||||
// This test read a lot of entries in `testdata/sign.input`
|
// This test read a lot of entries in `testdata/sign.input`
|
||||||
// so, maybe need a long time to finish.
|
// so, maybe need a long time to finish.
|
||||||
// be quiet and patient
|
// be quiet and patient
|
||||||
fn test_input_from_djb_ed25519_crypto_sign_input_with_syncpool() ? {
|
fn test_input_from_djb_ed25519_crypto_sign_input_with_syncpool() {
|
||||||
// contents := os.read_lines('testdata/sign.input') or { panic(err) } //[]string
|
// contents := os.read_lines('testdata/sign.input') or { panic(err) } //[]string
|
||||||
mut pool_s := pool.new_pool_processor(
|
mut pool_s := pool.new_pool_processor(
|
||||||
callback: worker_for_string_content
|
callback: worker_for_string_content
|
||||||
|
@ -174,10 +174,10 @@ fn test_input_from_djb_ed25519_crypto_sign_input_without_syncpool() ? {
|
||||||
lg.fatal('not contains len 5')
|
lg.fatal('not contains len 5')
|
||||||
}*/
|
}*/
|
||||||
assert parts.len == 5
|
assert parts.len == 5
|
||||||
privbytes := hex.decode(parts[0])?
|
privbytes := hex.decode(parts[0])!
|
||||||
pubkey := hex.decode(parts[1])?
|
pubkey := hex.decode(parts[1])!
|
||||||
msg := hex.decode(parts[2])?
|
msg := hex.decode(parts[2])!
|
||||||
mut sig := hex.decode(parts[3])?
|
mut sig := hex.decode(parts[3])!
|
||||||
assert pubkey.len == public_key_size
|
assert pubkey.len == public_key_size
|
||||||
|
|
||||||
sig = sig[..signature_size]
|
sig = sig[..signature_size]
|
||||||
|
@ -185,10 +185,10 @@ fn test_input_from_djb_ed25519_crypto_sign_input_without_syncpool() ? {
|
||||||
copy(mut priv[..], privbytes)
|
copy(mut priv[..], privbytes)
|
||||||
copy(mut priv[32..], pubkey)
|
copy(mut priv[32..], pubkey)
|
||||||
|
|
||||||
sig2 := ed25519.sign(priv[..], msg)?
|
sig2 := ed25519.sign(priv[..], msg)!
|
||||||
assert sig == sig2[..]
|
assert sig == sig2[..]
|
||||||
|
|
||||||
res := ed25519.verify(pubkey, msg, sig2)?
|
res := ed25519.verify(pubkey, msg, sig2)!
|
||||||
assert res == true
|
assert res == true
|
||||||
|
|
||||||
priv2 := new_key_from_seed(priv[..32])
|
priv2 := new_key_from_seed(priv[..32])
|
||||||
|
|
|
@ -624,7 +624,7 @@ pub fn (mut v Element) set(a Element) Element {
|
||||||
// Consistent with RFC 7748, the most significant bit (the high bit of the
|
// Consistent with RFC 7748, the most significant bit (the high bit of the
|
||||||
// last byte) is ignored, and non-canonical values (2^255-19 through 2^255-1)
|
// last byte) is ignored, and non-canonical values (2^255-19 through 2^255-1)
|
||||||
// are accepted. Note that this is laxer than specified by RFC 8032.
|
// are accepted. Note that this is laxer than specified by RFC 8032.
|
||||||
pub fn (mut v Element) set_bytes(x []u8) ?Element {
|
pub fn (mut v Element) set_bytes(x []u8) !Element {
|
||||||
if x.len != 32 {
|
if x.len != 32 {
|
||||||
return error('edwards25519: invalid edwards25519 element input size')
|
return error('edwards25519: invalid edwards25519 element input size')
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,7 +162,7 @@ struct SqrtRatioTest {
|
||||||
r string
|
r string
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_sqrt_ratio() ? {
|
fn test_sqrt_ratio() {
|
||||||
// From draft-irtf-cfrg-ristretto255-decaf448-00, Appendix A.4.
|
// From draft-irtf-cfrg-ristretto255-decaf448-00, Appendix A.4.
|
||||||
|
|
||||||
tests := [
|
tests := [
|
||||||
|
@ -188,9 +188,9 @@ fn test_sqrt_ratio() ? {
|
||||||
mut elw := Element{}
|
mut elw := Element{}
|
||||||
mut elg := Element{}
|
mut elg := Element{}
|
||||||
|
|
||||||
u := elu.set_bytes(hex.decode(tt.u)?)?
|
u := elu.set_bytes(hex.decode(tt.u)!)!
|
||||||
v := elv.set_bytes(hex.decode(tt.v)?)?
|
v := elv.set_bytes(hex.decode(tt.v)!)!
|
||||||
want := elw.set_bytes(hex.decode(tt.r)?)?
|
want := elw.set_bytes(hex.decode(tt.r)!)!
|
||||||
mut got, was_square := elg.sqrt_ratio(u, v)
|
mut got, was_square := elg.sqrt_ratio(u, v)
|
||||||
|
|
||||||
assert got.equal(want) != 0
|
assert got.equal(want) != 0
|
||||||
|
@ -201,12 +201,12 @@ fn test_sqrt_ratio() ? {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_set_bytes_normal() ? {
|
fn test_set_bytes_normal() {
|
||||||
for i in 0 .. 15 {
|
for i in 0 .. 15 {
|
||||||
mut el := Element{}
|
mut el := Element{}
|
||||||
mut random_inp := rand.bytes(32)?
|
mut random_inp := rand.bytes(32)!
|
||||||
|
|
||||||
el = el.set_bytes(random_inp.clone())?
|
el = el.set_bytes(random_inp.clone())!
|
||||||
random_inp[random_inp.len - 1] &= (1 << 7) - 1
|
random_inp[random_inp.len - 1] &= (1 << 7) - 1
|
||||||
// assert f1(random_inp, el) == true
|
// assert f1(random_inp, el) == true
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ mut:
|
||||||
b []u8
|
b []u8
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_set_bytes_from_dalek_test_vectors() ? {
|
fn test_set_bytes_from_dalek_test_vectors() {
|
||||||
mut tests := [
|
mut tests := [
|
||||||
FeRTTest{
|
FeRTTest{
|
||||||
fe: Element{358744748052810, 1691584618240980, 977650209285361, 1429865912637724, 560044844278676}
|
fe: Element{358744748052810, 1691584618240980, 977650209285361, 1429865912637724, 560044844278676}
|
||||||
|
@ -249,7 +249,7 @@ fn test_set_bytes_from_dalek_test_vectors() ? {
|
||||||
for _, mut tt in tests {
|
for _, mut tt in tests {
|
||||||
b := tt.fe.bytes()
|
b := tt.fe.bytes()
|
||||||
mut el := Element{}
|
mut el := Element{}
|
||||||
mut fe := el.set_bytes(tt.b)?
|
mut fe := el.set_bytes(tt.b)!
|
||||||
|
|
||||||
assert b == tt.b
|
assert b == tt.b
|
||||||
assert fe.equal(tt.fe) == 1
|
assert fe.equal(tt.fe) == 1
|
||||||
|
@ -267,7 +267,7 @@ fn test_equal() {
|
||||||
assert eq1 == 0
|
assert eq1 == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_invert() ? {
|
fn test_invert() {
|
||||||
mut x := Element{1, 1, 1, 1, 1}
|
mut x := Element{1, 1, 1, 1, 1}
|
||||||
mut one := Element{1, 0, 0, 0, 0}
|
mut one := Element{1, 0, 0, 0, 0}
|
||||||
mut xinv := Element{}
|
mut xinv := Element{}
|
||||||
|
@ -278,9 +278,9 @@ fn test_invert() ? {
|
||||||
r.reduce()
|
r.reduce()
|
||||||
|
|
||||||
assert one == r
|
assert one == r
|
||||||
bytes := rand.bytes(32) or { return err }
|
bytes := rand.bytes(32)!
|
||||||
|
|
||||||
x.set_bytes(bytes)?
|
x.set_bytes(bytes)!
|
||||||
|
|
||||||
xinv.invert(x)
|
xinv.invert(x)
|
||||||
r.multiply(x, xinv)
|
r.multiply(x, xinv)
|
||||||
|
@ -363,26 +363,26 @@ fn (mut v Element) to_big_integer() big.Integer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// from_big_integer sets v = n, and returns v. The bit length of n must not exceed 256.
|
// from_big_integer sets v = n, and returns v. The bit length of n must not exceed 256.
|
||||||
fn (mut v Element) from_big_integer(n big.Integer) ?Element {
|
fn (mut v Element) from_big_integer(n big.Integer) !Element {
|
||||||
if n.binary_str().len > 32 * 8 {
|
if n.binary_str().len > 32 * 8 {
|
||||||
return error('invalid edwards25519 element input size')
|
return error('invalid edwards25519 element input size')
|
||||||
}
|
}
|
||||||
mut bytes, _ := n.bytes()
|
mut bytes, _ := n.bytes()
|
||||||
swap_endianness(mut bytes) // SHOULD I SWAP IT?
|
swap_endianness(mut bytes) // SHOULD I SWAP IT?
|
||||||
v.set_bytes(bytes)?
|
v.set_bytes(bytes)!
|
||||||
|
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut v Element) from_decimal_string(s string) ?Element {
|
fn (mut v Element) from_decimal_string(s string) !Element {
|
||||||
num := big.integer_from_string(s)?
|
num := big.integer_from_string(s)!
|
||||||
|
|
||||||
v = v.from_big_integer(num)?
|
v = v.from_big_integer(num)!
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_bytes_big_equivalence() ? {
|
fn test_bytes_big_equivalence() {
|
||||||
mut inp := rand.bytes(32)?
|
mut inp := rand.bytes(32)!
|
||||||
el := Element{}
|
el := Element{}
|
||||||
mut fe := el.generate_element()
|
mut fe := el.generate_element()
|
||||||
mut fe1 := el.generate_element()
|
mut fe1 := el.generate_element()
|
||||||
|
@ -404,15 +404,15 @@ fn test_bytes_big_equivalence() ? {
|
||||||
// assert big_equivalence(inp, fe, fe1) == true
|
// assert big_equivalence(inp, fe, fe1) == true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_decimal_constants() ? {
|
fn test_decimal_constants() {
|
||||||
sqrtm1string := '19681161376707505956807079304988542015446066515923890162744021073123829784752'
|
sqrtm1string := '19681161376707505956807079304988542015446066515923890162744021073123829784752'
|
||||||
mut el := Element{}
|
mut el := Element{}
|
||||||
mut exp := el.from_decimal_string(sqrtm1string)?
|
mut exp := el.from_decimal_string(sqrtm1string)!
|
||||||
|
|
||||||
assert sqrt_m1.equal(exp) == 1
|
assert sqrt_m1.equal(exp) == 1
|
||||||
|
|
||||||
dstring := '37095705934669439343138083508754565189542113879843219016388785533085940283555'
|
dstring := '37095705934669439343138083508754565189542113879843219016388785533085940283555'
|
||||||
exp = el.from_decimal_string(dstring)?
|
exp = el.from_decimal_string(dstring)!
|
||||||
mut d := d_const
|
mut d := d_const
|
||||||
|
|
||||||
assert d.equal(exp) == 1
|
assert d.equal(exp) == 1
|
||||||
|
|
|
@ -44,12 +44,12 @@ fn test_bytes_montgomery() {
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
fn test_bytes_montgomery_sodium() ? {
|
fn test_bytes_montgomery_sodium() {
|
||||||
// Generated with libsodium.js 1.0.18
|
// Generated with libsodium.js 1.0.18
|
||||||
// crypto_sign_keypair().pubkey
|
// crypto_sign_keypair().pubkey
|
||||||
pubkey := '3bf918ffc2c955dc895bf145f566fb96623c1cadbe040091175764b5fde322c0'
|
pubkey := '3bf918ffc2c955dc895bf145f566fb96623c1cadbe040091175764b5fde322c0'
|
||||||
mut p := Point{}
|
mut p := Point{}
|
||||||
p.set_bytes(hex.decode(pubkey)?)?
|
p.set_bytes(hex.decode(pubkey)!)!
|
||||||
|
|
||||||
// crypto_sign_ed25519_pk_to_curve25519(pubkey)
|
// crypto_sign_ed25519_pk_to_curve25519(pubkey)
|
||||||
want := 'efc6c9d0738e9ea18d738ad4a2653631558931b0f1fde4dd58c436d19686dc28'
|
want := 'efc6c9d0738e9ea18d738ad4a2653631558931b0f1fde4dd58c436d19686dc28'
|
||||||
|
@ -113,9 +113,9 @@ fn fn_cofactor(mut data []u8) bool {
|
||||||
return p8.equal(pp) == 1
|
return p8.equal(pp) == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_mult_by_cofactor() ? {
|
fn test_mult_by_cofactor() {
|
||||||
mut loworder := Point{}
|
mut loworder := Point{}
|
||||||
mut data := rand.bytes(64)?
|
mut data := rand.bytes(64)!
|
||||||
|
|
||||||
assert fn_cofactor(mut data) == true
|
assert fn_cofactor(mut data) == true
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,30 +18,30 @@ const (
|
||||||
gen_point = generator() or { panic(err) }
|
gen_point = generator() or { panic(err) }
|
||||||
)
|
)
|
||||||
|
|
||||||
fn d_const_generate() ?Element {
|
fn d_const_generate() !Element {
|
||||||
mut v := Element{}
|
mut v := Element{}
|
||||||
v.set_bytes(edwards25519.d_bytes)?
|
v.set_bytes(edwards25519.d_bytes)!
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
fn d2_const_generate() ?Element {
|
fn d2_const_generate() !Element {
|
||||||
mut v := Element{}
|
mut v := Element{}
|
||||||
v.add(edwards25519.d_const, edwards25519.d_const)
|
v.add(edwards25519.d_const, edwards25519.d_const)
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
// id_point_generate is the point at infinity.
|
// id_point_generate is the point at infinity.
|
||||||
fn id_point_generate() ?Point {
|
fn id_point_generate() !Point {
|
||||||
mut p := Point{}
|
mut p := Point{}
|
||||||
p.set_bytes(edwards25519.id_bytes)?
|
p.set_bytes(edwards25519.id_bytes)!
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// generator is the canonical curve basepoint. See TestGenerator for the
|
// generator is the canonical curve basepoint. See TestGenerator for the
|
||||||
// correspondence of this encoding with the values in RFC 8032.
|
// correspondence of this encoding with the values in RFC 8032.
|
||||||
fn generator() ?Point {
|
fn generator() !Point {
|
||||||
mut p := Point{}
|
mut p := Point{}
|
||||||
p.set_bytes(edwards25519.gen_bytes)?
|
p.set_bytes(edwards25519.gen_bytes)!
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ fn (mut v ProjectiveP2) zero() ProjectiveP2 {
|
||||||
// Note that set_bytes accepts all non-canonical encodings of valid points.
|
// Note that set_bytes accepts all non-canonical encodings of valid points.
|
||||||
// That is, it follows decoding rules that match most implementations in
|
// That is, it follows decoding rules that match most implementations in
|
||||||
// the ecosystem rather than RFC 8032.
|
// the ecosystem rather than RFC 8032.
|
||||||
pub fn (mut v Point) set_bytes(x []u8) ?Point {
|
pub fn (mut v Point) set_bytes(x []u8) !Point {
|
||||||
// Specifically, the non-canonical encodings that are accepted are
|
// Specifically, the non-canonical encodings that are accepted are
|
||||||
// 1) the ones where the edwards25519 element is not reduced (see the
|
// 1) the ones where the edwards25519 element is not reduced (see the
|
||||||
// (*edwards25519.Element).set_bytes docs) and
|
// (*edwards25519.Element).set_bytes docs) and
|
||||||
|
|
|
@ -4,7 +4,7 @@ import encoding.hex
|
||||||
|
|
||||||
const zero_point = Point{fe_zero, fe_zero, fe_zero, fe_zero}
|
const zero_point = Point{fe_zero, fe_zero, fe_zero, fe_zero}
|
||||||
|
|
||||||
fn test_invalid_encodings() ? {
|
fn test_invalid_encodings() {
|
||||||
// An invalid point, that also happens to have y > p.
|
// An invalid point, that also happens to have y > p.
|
||||||
invalid := 'efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f'
|
invalid := 'efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f'
|
||||||
inv_bytes := hex.decode(invalid) or { panic(err) }
|
inv_bytes := hex.decode(invalid) or { panic(err) }
|
||||||
|
@ -17,7 +17,7 @@ fn test_invalid_encodings() ? {
|
||||||
assert check_on_curve(p) == true
|
assert check_on_curve(p) == true
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_add_sub_neg_on_basepoint() ? {
|
fn test_add_sub_neg_on_basepoint() {
|
||||||
bgp := new_generator_point()
|
bgp := new_generator_point()
|
||||||
mut idp := new_identity_point()
|
mut idp := new_identity_point()
|
||||||
mut checklhs := Point{}
|
mut checklhs := Point{}
|
||||||
|
@ -52,7 +52,7 @@ struct NonCanonicalTest {
|
||||||
canonical string
|
canonical string
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_non_canonical_points() ? {
|
fn test_non_canonical_points() {
|
||||||
tests := [
|
tests := [
|
||||||
// Points with x = 0 and the sign bit set. With x = 0 the curve equation
|
// Points with x = 0 and the sign bit set. With x = 0 the curve equation
|
||||||
// gives y² = 1, so y = ±1. 1 has two valid encodings.
|
// gives y² = 1, so y = ±1. 1 has two valid encodings.
|
||||||
|
@ -96,11 +96,11 @@ fn test_non_canonical_points() ? {
|
||||||
// t.Run(tt.name, func(t *testing.T) {
|
// t.Run(tt.name, func(t *testing.T) {
|
||||||
// p1, err := new(Point).SetBytes(decodeHex(tt.encoding))
|
// p1, err := new(Point).SetBytes(decodeHex(tt.encoding))
|
||||||
mut p1 := Point{}
|
mut p1 := Point{}
|
||||||
p1.set_bytes(hex.decode(tt.encoding)?)?
|
p1.set_bytes(hex.decode(tt.encoding)!)!
|
||||||
|
|
||||||
// p2, err := new(Point).SetBytes(decodeHex(tt.canonical))
|
// p2, err := new(Point).SetBytes(decodeHex(tt.canonical))
|
||||||
mut p2 := Point{}
|
mut p2 := Point{}
|
||||||
p2.set_bytes(hex.decode(tt.canonical)?)?
|
p2.set_bytes(hex.decode(tt.canonical)!)!
|
||||||
|
|
||||||
assert p1.equal(p2) == 1
|
assert p1.equal(p2) == 1
|
||||||
assert p1.bytes() == p2.bytes()
|
assert p1.bytes() == p2.bytes()
|
||||||
|
|
|
@ -86,7 +86,7 @@ pub fn (mut s Scalar) set(x Scalar) Scalar {
|
||||||
// set_uniform_bytes sets s to an uniformly distributed value given 64 uniformly
|
// set_uniform_bytes sets s to an uniformly distributed value given 64 uniformly
|
||||||
// distributed random bytes. If x is not of the right length, set_uniform_bytes
|
// distributed random bytes. If x is not of the right length, set_uniform_bytes
|
||||||
// returns an error, and the receiver is unchanged.
|
// returns an error, and the receiver is unchanged.
|
||||||
pub fn (mut s Scalar) set_uniform_bytes(x []u8) ?Scalar {
|
pub fn (mut s Scalar) set_uniform_bytes(x []u8) !Scalar {
|
||||||
if x.len != 64 {
|
if x.len != 64 {
|
||||||
return error('edwards25519: invalid set_uniform_bytes input length')
|
return error('edwards25519: invalid set_uniform_bytes input length')
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ pub fn (mut s Scalar) set_uniform_bytes(x []u8) ?Scalar {
|
||||||
// set_canonical_bytes sets s = x, where x is a 32-byte little-endian encoding of
|
// set_canonical_bytes sets s = x, where x is a 32-byte little-endian encoding of
|
||||||
// s, and returns s. If x is not a canonical encoding of s, set_canonical_bytes
|
// s, and returns s. If x is not a canonical encoding of s, set_canonical_bytes
|
||||||
// returns an error, and the receiver is unchanged.
|
// returns an error, and the receiver is unchanged.
|
||||||
pub fn (mut s Scalar) set_canonical_bytes(x []u8) ?Scalar {
|
pub fn (mut s Scalar) set_canonical_bytes(x []u8) !Scalar {
|
||||||
if x.len != 32 {
|
if x.len != 32 {
|
||||||
return error('invalid scalar length')
|
return error('invalid scalar length')
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ fn is_reduced(s Scalar) bool {
|
||||||
// expected as long as it is applied to points on the prime order subgroup, like
|
// expected as long as it is applied to points on the prime order subgroup, like
|
||||||
// in Ed25519. In fact, it is lost to history why RFC 8032 adopted the
|
// in Ed25519. In fact, it is lost to history why RFC 8032 adopted the
|
||||||
// irrelevant RFC 7748 clamping, but it is now required for compatibility.
|
// irrelevant RFC 7748 clamping, but it is now required for compatibility.
|
||||||
pub fn (mut s Scalar) set_bytes_with_clamping(x []u8) ?Scalar {
|
pub fn (mut s Scalar) set_bytes_with_clamping(x []u8) !Scalar {
|
||||||
// The description above omits the purpose of the high bits of the clamping
|
// The description above omits the purpose of the high bits of the clamping
|
||||||
// for brevity, but those are also lost to reductions, and are also
|
// for brevity, but those are also lost to reductions, and are also
|
||||||
// irrelevant to edwards25519 as they protect against a specific
|
// irrelevant to edwards25519 as they protect against a specific
|
||||||
|
@ -1070,7 +1070,7 @@ fn (mut s Scalar) signed_radix16() []i8 {
|
||||||
// utility function
|
// utility function
|
||||||
// generate returns a valid (reduced modulo l) Scalar with a distribution
|
// generate returns a valid (reduced modulo l) Scalar with a distribution
|
||||||
// weighted towards high, low, and edge values.
|
// weighted towards high, low, and edge values.
|
||||||
fn generate_scalar(size int) ?Scalar {
|
fn generate_scalar(size int) !Scalar {
|
||||||
/*
|
/*
|
||||||
s := scZero
|
s := scZero
|
||||||
diceRoll := rand.Intn(100)
|
diceRoll := rand.Intn(100)
|
||||||
|
@ -1115,7 +1115,7 @@ fn generate_scalar(size int) ?Scalar {
|
||||||
// rand.Read(s.s[:16]) // read random bytes and fill buf
|
// rand.Read(s.s[:16]) // read random bytes and fill buf
|
||||||
// using builtin rand.read([]buf)
|
// using builtin rand.read([]buf)
|
||||||
rand.read(mut s.s[..16])
|
rand.read(mut s.s[..16])
|
||||||
// buf := rand.read(s.s[..16].len)?
|
// buf := rand.read(s.s[..16].len)!
|
||||||
// copy(mut s.s[..16], buf)
|
// copy(mut s.s[..16], buf)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1132,7 +1132,7 @@ fn generate_scalar(size int) ?Scalar {
|
||||||
// Read generates len(p) random bytes and writes them into p
|
// Read generates len(p) random bytes and writes them into p
|
||||||
// rand.Read(s.s[:16])
|
// rand.Read(s.s[:16])
|
||||||
rand.read(mut s.s[..16])
|
rand.read(mut s.s[..16])
|
||||||
// buf := rand.read(s.s[..16].len)?
|
// buf := rand.read(s.s[..16].len)!
|
||||||
// copy(mut s.s[..16], buf)
|
// copy(mut s.s[..16], buf)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1148,7 +1148,7 @@ fn generate_scalar(size int) ?Scalar {
|
||||||
// of being out of the latter range).
|
// of being out of the latter range).
|
||||||
// rand.Read(s.s[:])
|
// rand.Read(s.s[:])
|
||||||
rand.read(mut s.s[..])
|
rand.read(mut s.s[..])
|
||||||
// buf := crand.read(s.s.len)?
|
// buf := crand.read(s.s.len)!
|
||||||
// copy(mut s.s[..], buf)
|
// copy(mut s.s[..], buf)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1164,10 +1164,10 @@ fn generate_scalar(size int) ?Scalar {
|
||||||
|
|
||||||
type NotZeroScalar = Scalar
|
type NotZeroScalar = Scalar
|
||||||
|
|
||||||
fn generate_notzero_scalar(size int) ?NotZeroScalar {
|
fn generate_notzero_scalar(size int) !NotZeroScalar {
|
||||||
mut s := Scalar{}
|
mut s := Scalar{}
|
||||||
for s == edwards25519.sc_zero {
|
for s == edwards25519.sc_zero {
|
||||||
s = generate_scalar(size)?
|
s = generate_scalar(size)!
|
||||||
}
|
}
|
||||||
return NotZeroScalar(s)
|
return NotZeroScalar(s)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,9 +24,9 @@ fn negate_aliasing(mut v Scalar, x Scalar) Scalar {
|
||||||
return v.negate(x)
|
return v.negate(x)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_check_aliasing_oneargs() ? {
|
fn test_check_aliasing_oneargs() {
|
||||||
x := generate_notzero_scalar(10)?
|
x := generate_notzero_scalar(10)!
|
||||||
mut v := generate_notzero_scalar(10)?
|
mut v := generate_notzero_scalar(10)!
|
||||||
out := check_aliasing_onearg(negate_aliasing, mut v, x)
|
out := check_aliasing_onearg(negate_aliasing, mut v, x)
|
||||||
assert out == true
|
assert out == true
|
||||||
}
|
}
|
||||||
|
@ -43,12 +43,12 @@ fn subtract_aliasing(mut v Scalar, x Scalar, y Scalar) Scalar {
|
||||||
return v.subtract(x, y)
|
return v.subtract(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_check_aliasing_twoargs() ? {
|
fn test_check_aliasing_twoargs() {
|
||||||
fn_with_twoargs := [add_aliasing, multiply_aliasing, subtract_aliasing]
|
fn_with_twoargs := [add_aliasing, multiply_aliasing, subtract_aliasing]
|
||||||
for f in fn_with_twoargs {
|
for f in fn_with_twoargs {
|
||||||
mut v := generate_notzero_scalar(10)?
|
mut v := generate_notzero_scalar(10)!
|
||||||
x := generate_notzero_scalar(10)?
|
x := generate_notzero_scalar(10)!
|
||||||
y := generate_notzero_scalar(10)?
|
y := generate_notzero_scalar(10)!
|
||||||
out := check_aliasing_twoargs(f, mut v, x, y)
|
out := check_aliasing_twoargs(f, mut v, x, y)
|
||||||
assert out == true
|
assert out == true
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ fn fg(sc Scalar) bool {
|
||||||
return is_reduced(sc)
|
return is_reduced(sc)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_scalar_generate() ? {
|
fn test_scalar_generate() {
|
||||||
for i in 0 .. 15 {
|
for i in 0 .. 15 {
|
||||||
sc := generate_scalar(1000) or { panic(err) }
|
sc := generate_scalar(1000) or { panic(err) }
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ fn test_scalar_generate() ? {
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
fn test_scalar_set_canonical_bytes() ? {
|
fn test_scalar_set_canonical_bytes() {
|
||||||
for i in 0 .. 10 {
|
for i in 0 .. 10 {
|
||||||
mut buf := rand.bytes(32) or { panic(err) }
|
mut buf := rand.bytes(32) or { panic(err) }
|
||||||
mut sc := generate_scalar(1000) or { panic(err) }
|
mut sc := generate_scalar(1000) or { panic(err) }
|
||||||
|
@ -89,10 +89,10 @@ fn test_scalar_set_canonical_bytes() ? {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_scalar_set_canonical_bytes_round_trip() ? {
|
fn test_scalar_set_canonical_bytes_round_trip() {
|
||||||
for i in 0 .. 10 {
|
for i in 0 .. 10 {
|
||||||
mut sc1 := generate_scalar(2)?
|
mut sc1 := generate_scalar(2)!
|
||||||
mut sc2 := generate_scalar(6)?
|
mut sc2 := generate_scalar(6)!
|
||||||
sc2.set_canonical_bytes(sc1.bytes()) or { panic(err) }
|
sc2.set_canonical_bytes(sc1.bytes()) or { panic(err) }
|
||||||
|
|
||||||
assert sc1 == sc2
|
assert sc1 == sc2
|
||||||
|
@ -105,7 +105,7 @@ const (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
fn test_scalar_set_canonical_bytes_on_noncanonical_value() ? {
|
fn test_scalar_set_canonical_bytes_on_noncanonical_value() {
|
||||||
mut b := sc_minus_one.s
|
mut b := sc_minus_one.s
|
||||||
b[31] += 1
|
b[31] += 1
|
||||||
|
|
||||||
|
@ -115,16 +115,16 @@ fn test_scalar_set_canonical_bytes_on_noncanonical_value() ? {
|
||||||
assert s == sc_one
|
assert s == sc_one
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_scalar_set_uniform_bytes() ? {
|
fn test_scalar_set_uniform_bytes() {
|
||||||
// mod, _ := new(big.Integer).SetString("27742317777372353535851937790883648493", 10)
|
// mod, _ := new(big.Integer).SetString("27742317777372353535851937790883648493", 10)
|
||||||
mut mod := big.integer_from_string('27742317777372353535851937790883648493')?
|
mut mod := big.integer_from_string('27742317777372353535851937790883648493')!
|
||||||
// mod.Add(mod, new(big.Integer).Lsh(big.NewInt(1), 252))
|
// mod.Add(mod, new(big.Integer).Lsh(big.NewInt(1), 252))
|
||||||
mod = mod + big.integer_from_i64(1).lshift(252)
|
mod = mod + big.integer_from_i64(1).lshift(252)
|
||||||
|
|
||||||
mut sc := generate_scalar(100)?
|
mut sc := generate_scalar(100)!
|
||||||
inp := rand.bytes(64)?
|
inp := rand.bytes(64)!
|
||||||
|
|
||||||
sc.set_uniform_bytes(inp[..])?
|
sc.set_uniform_bytes(inp[..])!
|
||||||
assert is_reduced(sc) == true
|
assert is_reduced(sc) == true
|
||||||
|
|
||||||
scbig := bigint_from_le_bytes(sc.s[..])
|
scbig := bigint_from_le_bytes(sc.s[..])
|
||||||
|
@ -189,10 +189,10 @@ fn test_scalar_set_bytes_with_clamping() {
|
||||||
assert want2 == got2
|
assert want2 == got2
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_scalar_multiply_distributes_over_add() ? {
|
fn test_scalar_multiply_distributes_over_add() {
|
||||||
x := generate_scalar(100)?
|
x := generate_scalar(100)!
|
||||||
y := generate_scalar(100)?
|
y := generate_scalar(100)!
|
||||||
z := generate_scalar(100)?
|
z := generate_scalar(100)!
|
||||||
|
|
||||||
// Compute t1 = (x+y)*z
|
// Compute t1 = (x+y)*z
|
||||||
mut t1 := Scalar{}
|
mut t1 := Scalar{}
|
||||||
|
|
|
@ -91,11 +91,11 @@ fn test_scalar_mult_distributes_over_add() {
|
||||||
assert check.equal(r) == 1
|
assert check.equal(r) == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_scalarmult_non_identity_point() ? {
|
fn test_scalarmult_non_identity_point() {
|
||||||
// Check whether p.ScalarMult and q.ScalaBaseMult give the same,
|
// Check whether p.ScalarMult and q.ScalaBaseMult give the same,
|
||||||
// when p and q are originally set to the base point.
|
// when p and q are originally set to the base point.
|
||||||
|
|
||||||
mut x := generate_scalar(5000)?
|
mut x := generate_scalar(5000)!
|
||||||
|
|
||||||
mut p := Point{}
|
mut p := Point{}
|
||||||
mut q := Point{}
|
mut q := Point{}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import crypto.rand
|
import crypto.rand
|
||||||
|
|
||||||
fn test_reading() ? {
|
fn test_reading() {
|
||||||
a := rand.read(32)?
|
a := rand.read(32)!
|
||||||
// dump(a.hex())
|
// dump(a.hex())
|
||||||
assert a.len == 32
|
assert a.len == 32
|
||||||
mut histogram := [256]int{}
|
mut histogram := [256]int{}
|
||||||
|
|
|
@ -18,6 +18,6 @@ pub fn (err ReadError) msg() string {
|
||||||
// See also rand.bytes(), if you do not need really random bytes,
|
// See also rand.bytes(), if you do not need really random bytes,
|
||||||
// but instead pseudo random ones, from a pseudo random generator
|
// but instead pseudo random ones, from a pseudo random generator
|
||||||
// that can be seeded, and that is usually faster.
|
// that can be seeded, and that is usually faster.
|
||||||
pub fn bytes(bytes_needed int) ?[]u8 {
|
pub fn bytes(bytes_needed int) ![]u8 {
|
||||||
return read(bytes_needed)
|
return read(bytes_needed)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ module rand
|
||||||
fn C.SecRandomCopyBytes(rnd C.SecRandomRef, count usize, bytes voidptr) int
|
fn C.SecRandomCopyBytes(rnd C.SecRandomRef, count usize, bytes voidptr) int
|
||||||
|
|
||||||
// read returns an array of `bytes_needed` random bytes read from the OS.
|
// read returns an array of `bytes_needed` random bytes read from the OS.
|
||||||
pub fn read(bytes_needed int) ?[]u8 {
|
pub fn read(bytes_needed int) ![]u8 {
|
||||||
mut buffer := []u8{len: bytes_needed}
|
mut buffer := []u8{len: bytes_needed}
|
||||||
status := C.SecRandomCopyBytes(C.SecRandomRef(0), bytes_needed, buffer.data)
|
status := C.SecRandomCopyBytes(C.SecRandomRef(0), bytes_needed, buffer.data)
|
||||||
if status != 0 {
|
if status != 0 {
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
module rand
|
module rand
|
||||||
|
|
||||||
// read returns an array of `bytes_needed` random bytes read from the OS.
|
// read returns an array of `bytes_needed` random bytes read from the OS.
|
||||||
pub fn read(bytes_needed int) ?[]u8 {
|
pub fn read(bytes_needed int) ![]u8 {
|
||||||
return error('rand.read is not implemented on this platform')
|
return error('rand.read is not implemented on this platform')
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ module rand
|
||||||
fn C.arc4random_buf(p &byte, n usize)
|
fn C.arc4random_buf(p &byte, n usize)
|
||||||
|
|
||||||
// read returns an array of `bytes_needed` random bytes read from the OS.
|
// read returns an array of `bytes_needed` random bytes read from the OS.
|
||||||
pub fn read(bytes_needed int) ?[]u8 {
|
pub fn read(bytes_needed int) ![]u8 {
|
||||||
mut buffer := unsafe { malloc_noscan(bytes_needed) }
|
mut buffer := unsafe { malloc_noscan(bytes_needed) }
|
||||||
C.arc4random_buf(buffer, bytes_needed)
|
C.arc4random_buf(buffer, bytes_needed)
|
||||||
return unsafe { buffer.vbytes(bytes_needed) }
|
return unsafe { buffer.vbytes(bytes_needed) }
|
||||||
|
|
|
@ -10,7 +10,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// read returns an array of `bytes_needed` random bytes read from the OS.
|
// read returns an array of `bytes_needed` random bytes read from the OS.
|
||||||
pub fn read(bytes_needed int) ?[]u8 {
|
pub fn read(bytes_needed int) ![]u8 {
|
||||||
mut buffer := unsafe { vcalloc_noscan(bytes_needed) }
|
mut buffer := unsafe { vcalloc_noscan(bytes_needed) }
|
||||||
mut bytes_read := 0
|
mut bytes_read := 0
|
||||||
mut remaining_bytes := bytes_needed
|
mut remaining_bytes := bytes_needed
|
||||||
|
|
|
@ -9,7 +9,7 @@ module rand
|
||||||
fn C.arc4random_buf(p &byte, n usize)
|
fn C.arc4random_buf(p &byte, n usize)
|
||||||
|
|
||||||
// read returns an array of `bytes_needed` random bytes read from the OS.
|
// read returns an array of `bytes_needed` random bytes read from the OS.
|
||||||
pub fn read(bytes_needed int) ?[]u8 {
|
pub fn read(bytes_needed int) ![]u8 {
|
||||||
mut buffer := unsafe { malloc_noscan(bytes_needed) }
|
mut buffer := unsafe { malloc_noscan(bytes_needed) }
|
||||||
C.arc4random_buf(buffer, bytes_needed)
|
C.arc4random_buf(buffer, bytes_needed)
|
||||||
return unsafe { buffer.vbytes(bytes_needed) }
|
return unsafe { buffer.vbytes(bytes_needed) }
|
||||||
|
|
|
@ -13,7 +13,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// read returns an array of `bytes_needed` random bytes read from the OS.
|
// read returns an array of `bytes_needed` random bytes read from the OS.
|
||||||
pub fn read(bytes_needed int) ?[]u8 {
|
pub fn read(bytes_needed int) ![]u8 {
|
||||||
mut buffer := unsafe { malloc_noscan(bytes_needed) }
|
mut buffer := unsafe { malloc_noscan(bytes_needed) }
|
||||||
mut bytes_read := 0
|
mut bytes_read := 0
|
||||||
mut remaining_bytes := bytes_needed
|
mut remaining_bytes := bytes_needed
|
||||||
|
|
|
@ -14,7 +14,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
// read returns an array of `bytes_needed` random bytes read from the OS.
|
// read returns an array of `bytes_needed` random bytes read from the OS.
|
||||||
pub fn read(bytes_needed int) ?[]u8 {
|
pub fn read(bytes_needed int) ![]u8 {
|
||||||
mut buffer := []u8{len: bytes_needed}
|
mut buffer := []u8{len: bytes_needed}
|
||||||
// use bcrypt_use_system_preferred_rng because we passed null as algo
|
// use bcrypt_use_system_preferred_rng because we passed null as algo
|
||||||
status := C.BCryptGenRandom(0, buffer.data, bytes_needed, rand.bcrypt_use_system_preferred_rng)
|
status := C.BCryptGenRandom(0, buffer.data, bytes_needed, rand.bcrypt_use_system_preferred_rng)
|
||||||
|
|
|
@ -8,7 +8,7 @@ import math.bits
|
||||||
import encoding.binary
|
import encoding.binary
|
||||||
|
|
||||||
// int_u64 returns a random unsigned 64-bit integer `u64` read from a real OS source of entropy.
|
// int_u64 returns a random unsigned 64-bit integer `u64` read from a real OS source of entropy.
|
||||||
pub fn int_u64(max u64) ?u64 {
|
pub fn int_u64(max u64) !u64 {
|
||||||
bitlen := bits.len_64(max)
|
bitlen := bits.len_64(max)
|
||||||
if bitlen == 0 {
|
if bitlen == 0 {
|
||||||
return u64(0)
|
return u64(0)
|
||||||
|
@ -20,7 +20,7 @@ pub fn int_u64(max u64) ?u64 {
|
||||||
}
|
}
|
||||||
mut n := u64(0)
|
mut n := u64(0)
|
||||||
for {
|
for {
|
||||||
mut bytes := read(k)?
|
mut bytes := read(k)!
|
||||||
bytes[0] &= u8(int(u64(1) << b) - 1)
|
bytes[0] &= u8(int(u64(1) << b) - 1)
|
||||||
x := bytes_to_u64(bytes)
|
x := bytes_to_u64(bytes)
|
||||||
n = x[0]
|
n = x[0]
|
||||||
|
|
|
@ -22,7 +22,7 @@ mut:
|
||||||
|
|
||||||
// new_cipher creates and returns a new Cipher. The key argument should be the
|
// new_cipher creates and returns a new Cipher. The key argument should be the
|
||||||
// RC4 key, at least 1 byte and at most 256 bytes.
|
// RC4 key, at least 1 byte and at most 256 bytes.
|
||||||
pub fn new_cipher(key []u8) ?Cipher {
|
pub fn new_cipher(key []u8) !Cipher {
|
||||||
if key.len < 1 || key.len > 256 {
|
if key.len < 1 || key.len > 256 {
|
||||||
return error('crypto.rc4: invalid key size ' + key.len.str())
|
return error('crypto.rc4: invalid key size ' + key.len.str())
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ pub fn new() &Digest {
|
||||||
|
|
||||||
// write writes the contents of `p_` to the internal hash representation.
|
// write writes the contents of `p_` to the internal hash representation.
|
||||||
[manualfree]
|
[manualfree]
|
||||||
pub fn (mut d Digest) write(p_ []u8) ?int {
|
pub fn (mut d Digest) write(p_ []u8) !int {
|
||||||
nn := p_.len
|
nn := p_.len
|
||||||
unsafe {
|
unsafe {
|
||||||
mut p := p_
|
mut p := p_
|
||||||
|
|
|
@ -90,7 +90,7 @@ pub fn new224() &Digest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// write writes the contents of `p_` to the internal hash representation.
|
// write writes the contents of `p_` to the internal hash representation.
|
||||||
pub fn (mut d Digest) write(p_ []u8) ?int {
|
pub fn (mut d Digest) write(p_ []u8) !int {
|
||||||
unsafe {
|
unsafe {
|
||||||
mut p := p_
|
mut p := p_
|
||||||
nn := p.len
|
nn := p.len
|
||||||
|
|
|
@ -149,7 +149,7 @@ fn new384() &Digest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// write writes the contents of `p_` to the internal hash representation.
|
// write writes the contents of `p_` to the internal hash representation.
|
||||||
pub fn (mut d Digest) write(p_ []u8) ?int {
|
pub fn (mut d Digest) write(p_ []u8) !int {
|
||||||
unsafe {
|
unsafe {
|
||||||
mut p := p_
|
mut p := p_
|
||||||
nn := p.len
|
nn := p.len
|
||||||
|
|
|
@ -42,7 +42,7 @@ pub fn (alphabet Alphabet) str() string {
|
||||||
|
|
||||||
// new_alphabet instantiates an Alphabet object based on
|
// new_alphabet instantiates an Alphabet object based on
|
||||||
// the provided characters
|
// the provided characters
|
||||||
pub fn new_alphabet(str string) ?Alphabet {
|
pub fn new_alphabet(str string) !Alphabet {
|
||||||
if str.len != 58 {
|
if str.len != 58 {
|
||||||
return error(@MOD + '.' + @FN + ': string must be 58 characters in length')
|
return error(@MOD + '.' + @FN + ': string must be 58 characters in length')
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,12 @@ module base58
|
||||||
import math
|
import math
|
||||||
|
|
||||||
// encode_int encodes any integer type to base58 string with Bitcoin alphabet
|
// encode_int encodes any integer type to base58 string with Bitcoin alphabet
|
||||||
pub fn encode_int(input int) ?string {
|
pub fn encode_int(input int) !string {
|
||||||
return encode_int_walpha(input, btc_alphabet)
|
return encode_int_walpha(input, btc_alphabet)
|
||||||
}
|
}
|
||||||
|
|
||||||
// encode_int_walpha any integer type to base58 string with custom alphabet
|
// encode_int_walpha any integer type to base58 string with custom alphabet
|
||||||
pub fn encode_int_walpha(input int, alphabet Alphabet) ?string {
|
pub fn encode_int_walpha(input int, alphabet Alphabet) !string {
|
||||||
if input <= 0 {
|
if input <= 0 {
|
||||||
return error(@MOD + '.' + @FN + ': input must be greater than zero')
|
return error(@MOD + '.' + @FN + ': input must be greater than zero')
|
||||||
}
|
}
|
||||||
|
@ -97,12 +97,12 @@ pub fn encode_walpha_bytes(input []u8, alphabet Alphabet) []u8 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode_int decodes base58 string to an integer with Bitcoin alphabet
|
// decode_int decodes base58 string to an integer with Bitcoin alphabet
|
||||||
pub fn decode_int(input string) ?int {
|
pub fn decode_int(input string) !int {
|
||||||
return decode_int_walpha(input, btc_alphabet)
|
return decode_int_walpha(input, btc_alphabet)
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode_int_walpha decodes base58 string to an integer with custom alphabet
|
// decode_int_walpha decodes base58 string to an integer with custom alphabet
|
||||||
pub fn decode_int_walpha(input string, alphabet Alphabet) ?int {
|
pub fn decode_int_walpha(input string, alphabet Alphabet) !int {
|
||||||
mut total := 0 // to hold the results
|
mut total := 0 // to hold the results
|
||||||
b58 := input.reverse()
|
b58 := input.reverse()
|
||||||
for i, ch in b58 {
|
for i, ch in b58 {
|
||||||
|
@ -121,27 +121,27 @@ pub fn decode_int_walpha(input string, alphabet Alphabet) ?int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode decodes the base58 input string, using the Bitcoin alphabet
|
// decode decodes the base58 input string, using the Bitcoin alphabet
|
||||||
pub fn decode(str string) ?string {
|
pub fn decode(str string) !string {
|
||||||
return decode_walpha(str, btc_alphabet)
|
return decode_walpha(str, btc_alphabet)
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode_bytes decodes the base58 encoded input array, using the Bitcoin alphabet
|
// decode_bytes decodes the base58 encoded input array, using the Bitcoin alphabet
|
||||||
pub fn decode_bytes(input []u8) ?[]u8 {
|
pub fn decode_bytes(input []u8) ![]u8 {
|
||||||
return decode_walpha_bytes(input, btc_alphabet)
|
return decode_walpha_bytes(input, btc_alphabet)
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode_walpha decodes the base58 encoded input string, using custom alphabet
|
// decode_walpha decodes the base58 encoded input string, using custom alphabet
|
||||||
pub fn decode_walpha(input string, alphabet Alphabet) ?string {
|
pub fn decode_walpha(input string, alphabet Alphabet) !string {
|
||||||
if input.len == 0 {
|
if input.len == 0 {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
bin := input.bytes()
|
bin := input.bytes()
|
||||||
res := decode_walpha_bytes(bin, alphabet)?
|
res := decode_walpha_bytes(bin, alphabet)!
|
||||||
return res.bytestr()
|
return res.bytestr()
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode_walpha_bytes decodes the base58 encoded input array using a custom alphabet
|
// decode_walpha_bytes decodes the base58 encoded input array using a custom alphabet
|
||||||
pub fn decode_walpha_bytes(input []u8, alphabet Alphabet) ?[]u8 {
|
pub fn decode_walpha_bytes(input []u8, alphabet Alphabet) ![]u8 {
|
||||||
if input.len == 0 {
|
if input.len == 0 {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +1,34 @@
|
||||||
module base58
|
module base58
|
||||||
|
|
||||||
fn main() {
|
fn test_encode_int() {
|
||||||
test_encode_int() or {}
|
|
||||||
test_decode_int() or {}
|
|
||||||
test_encode_string()
|
|
||||||
test_fails() or {}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_encode_int() ? {
|
|
||||||
a := 0x24 // should be 'd' in base58
|
a := 0x24 // should be 'd' in base58
|
||||||
assert encode_int(a)? == 'd'
|
assert encode_int(a)! == 'd'
|
||||||
|
|
||||||
test_encode_int_walpha()?
|
test_encode_int_walpha()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_encode_int_walpha() ? {
|
fn test_encode_int_walpha() {
|
||||||
// random alphabet
|
// random alphabet
|
||||||
abc := new_alphabet('abcdefghij\$lmnopqrstuvwxyz0123456789_ABCDEFGHIJLMNOPQRSTUV') or {
|
abc := new_alphabet('abcdefghij\$lmnopqrstuvwxyz0123456789_ABCDEFGHIJLMNOPQRSTUV') or {
|
||||||
panic(@MOD + '.' + @FN + ': this should never happen')
|
panic(@MOD + '.' + @FN + ': this should never happen')
|
||||||
}
|
}
|
||||||
a := 0x24 // should be '_' in base58 with our custom alphabet
|
a := 0x24 // should be '_' in base58 with our custom alphabet
|
||||||
assert encode_int_walpha(a, abc)? == '_'
|
assert encode_int_walpha(a, abc)! == '_'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_decode_int() ? {
|
fn test_decode_int() {
|
||||||
a := 'd'
|
a := 'd'
|
||||||
assert decode_int(a)? == 0x24
|
assert decode_int(a)! == 0x24
|
||||||
|
|
||||||
test_decode_int_walpha()?
|
test_decode_int_walpha()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_decode_int_walpha() ? {
|
fn test_decode_int_walpha() {
|
||||||
abc := new_alphabet('abcdefghij\$lmnopqrstuvwxyz0123456789_ABCDEFGHIJLMNOPQRSTUV') or {
|
abc := new_alphabet('abcdefghij\$lmnopqrstuvwxyz0123456789_ABCDEFGHIJLMNOPQRSTUV') or {
|
||||||
panic(@MOD + '.' + @FN + ': this should never happen')
|
panic(@MOD + '.' + @FN + ': this should never happen')
|
||||||
}
|
}
|
||||||
a := '_'
|
a := '_'
|
||||||
assert decode_int_walpha(a, abc)? == 0x24
|
assert decode_int_walpha(a, abc)! == 0x24
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_encode_string() {
|
fn test_encode_string() {
|
||||||
|
@ -49,18 +42,18 @@ fn test_encode_string() {
|
||||||
assert encode_walpha(a, abc) == '0P7yfPSL0pQh2L5'
|
assert encode_walpha(a, abc) == '0P7yfPSL0pQh2L5'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_decode_string() ? {
|
fn test_decode_string() {
|
||||||
a := 'TtaR6twpTGu8VpY'
|
a := 'TtaR6twpTGu8VpY'
|
||||||
assert decode(a)? == 'lorem ipsum'
|
assert decode(a)! == 'lorem ipsum'
|
||||||
|
|
||||||
abc := new_alphabet('abcdefghij\$lmnopqrstuvwxyz0123456789_ABCDEFGHIJLMNOPQRSTUV') or {
|
abc := new_alphabet('abcdefghij\$lmnopqrstuvwxyz0123456789_ABCDEFGHIJLMNOPQRSTUV') or {
|
||||||
panic(@MOD + '.' + @FN + ': this should never happen')
|
panic(@MOD + '.' + @FN + ': this should never happen')
|
||||||
}
|
}
|
||||||
b := '0P7yfPSL0pQh2L5'
|
b := '0P7yfPSL0pQh2L5'
|
||||||
assert decode_walpha(b, abc)? == 'lorem ipsum'
|
assert decode_walpha(b, abc)! == 'lorem ipsum'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_fails() ? {
|
fn test_fails() ! {
|
||||||
a := -238
|
a := -238
|
||||||
b := 0
|
b := 0
|
||||||
if z := encode_int(a) {
|
if z := encode_int(a) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import encoding.base58
|
import encoding.base58
|
||||||
import encoding.hex
|
import encoding.hex
|
||||||
|
|
||||||
fn test_encode() ? {
|
fn test_encode() {
|
||||||
for input, expected in {
|
for input, expected in {
|
||||||
'': ''
|
'': ''
|
||||||
'6263': '2PMCRQ'
|
'6263': '2PMCRQ'
|
||||||
|
@ -14,20 +14,20 @@ fn test_encode() ? {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_encode_int() ? {
|
fn test_encode_int() {
|
||||||
for input, expected in {
|
for input, expected in {
|
||||||
0x6263: '8VG'
|
0x6263: '8VG'
|
||||||
0x61: '2g'
|
0x61: '2g'
|
||||||
0x626262: 'a3gV'
|
0x626262: 'a3gV'
|
||||||
0x636363: 'aPEr'
|
0x636363: 'aPEr'
|
||||||
} {
|
} {
|
||||||
output := base58.encode_int(input)?
|
output := base58.encode_int(input)!
|
||||||
println('> input: 0x${input:x} | => output: `$output`')
|
println('> input: 0x${input:x} | => output: `$output`')
|
||||||
assert output == expected
|
assert output == expected
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_decode() ? {
|
fn test_decode() {
|
||||||
for output, expected in {
|
for output, expected in {
|
||||||
'USm3fpXnKG5EUBx2ndxBDMPVciP5hGey2Jh4NDv6gmeo1LkMeiKrLJUUBk6Z': 'The quick brown fox jumps over the lazy dog.'
|
'USm3fpXnKG5EUBx2ndxBDMPVciP5hGey2Jh4NDv6gmeo1LkMeiKrLJUUBk6Z': 'The quick brown fox jumps over the lazy dog.'
|
||||||
'11StV1DL6CwTryKyV': '\x00\x00hello world'
|
'11StV1DL6CwTryKyV': '\x00\x00hello world'
|
||||||
|
@ -35,7 +35,7 @@ fn test_decode() ? {
|
||||||
'14cxpo3MBCYYWCgF74SWTdcmxipnGUsPw3': hex.decode('0027b5891b01da2db74cde1689a97a2acbe23d5fb1c0205bf6')?.bytestr()
|
'14cxpo3MBCYYWCgF74SWTdcmxipnGUsPw3': hex.decode('0027b5891b01da2db74cde1689a97a2acbe23d5fb1c0205bf6')?.bytestr()
|
||||||
'3vQB7B6MrGQZaxCuFg4oh': hex.decode('68656c6c6f20776f726c64bc62d4b8')?.bytestr()
|
'3vQB7B6MrGQZaxCuFg4oh': hex.decode('68656c6c6f20776f726c64bc62d4b8')?.bytestr()
|
||||||
} {
|
} {
|
||||||
input := base58.decode(output)?
|
input := base58.decode(output)!
|
||||||
println('> output: `$output` | decoded input: `$input` | bytes: $input.bytes().hex()')
|
println('> output: `$output` | decoded input: `$input` | bytes: $input.bytes().hex()')
|
||||||
assert input.bytes().hex() == expected.bytes().hex()
|
assert input.bytes().hex() == expected.bytes().hex()
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,8 +68,8 @@ pub fn new_reader(data string, config ReaderConfig) &Reader {
|
||||||
|
|
||||||
// read reads a row from the CSV data.
|
// read reads a row from the CSV data.
|
||||||
// If successful, the result holds an array of each column's data.
|
// If successful, the result holds an array of each column's data.
|
||||||
pub fn (mut r Reader) read() ?[]string {
|
pub fn (mut r Reader) read() ![]string {
|
||||||
l := r.read_record()?
|
l := r.read_record()!
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ pub fn (mut r Reader) read() ?[]string {
|
||||||
// }
|
// }
|
||||||
// return records
|
// return records
|
||||||
// }
|
// }
|
||||||
fn (mut r Reader) read_line() ?string {
|
fn (mut r Reader) read_line() !string {
|
||||||
// last record
|
// last record
|
||||||
if r.row_pos == r.data.len {
|
if r.row_pos == r.data.len {
|
||||||
return IError(&EndOfFileError{})
|
return IError(&EndOfFileError{})
|
||||||
|
@ -119,7 +119,7 @@ fn (mut r Reader) read_line() ?string {
|
||||||
return line
|
return line
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut r Reader) read_record() ?[]string {
|
fn (mut r Reader) read_record() ![]string {
|
||||||
if r.delimiter == r.comment {
|
if r.delimiter == r.comment {
|
||||||
return IError(&CommentIsDelimiterError{})
|
return IError(&CommentIsDelimiterError{})
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ fn (mut r Reader) read_record() ?[]string {
|
||||||
mut i := -1
|
mut i := -1
|
||||||
for {
|
for {
|
||||||
if need_read {
|
if need_read {
|
||||||
l := r.read_line()?
|
l := r.read_line()!
|
||||||
if l.len <= 0 {
|
if l.len <= 0 {
|
||||||
if keep_raw {
|
if keep_raw {
|
||||||
line += '\n'
|
line += '\n'
|
||||||
|
|
|
@ -28,7 +28,7 @@ pub fn new_writer(config WriterConfig) &Writer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// write writes a single record
|
// write writes a single record
|
||||||
pub fn (mut w Writer) write(record []string) ?bool {
|
pub fn (mut w Writer) write(record []string) !bool {
|
||||||
if !valid_delim(w.delimiter) {
|
if !valid_delim(w.delimiter) {
|
||||||
return IError(&InvalidDelimiterError{})
|
return IError(&InvalidDelimiterError{})
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import strings
|
||||||
// decode converts a hex string into an array of bytes. The expected
|
// decode converts a hex string into an array of bytes. The expected
|
||||||
// input format is 2 ASCII characters for each output byte. If the provided
|
// input format is 2 ASCII characters for each output byte. If the provided
|
||||||
// string length is not a multiple of 2, an implicit `0` is prepended to it.
|
// string length is not a multiple of 2, an implicit `0` is prepended to it.
|
||||||
pub fn decode(s string) ?[]u8 {
|
pub fn decode(s string) ![]u8 {
|
||||||
mut hex_str := s
|
mut hex_str := s
|
||||||
if hex_str.len >= 2 {
|
if hex_str.len >= 2 {
|
||||||
if s[0] == `0` && (s[1] == `x` || s[1] == `X`) {
|
if s[0] == `0` && (s[1] == `x` || s[1] == `X`) {
|
||||||
|
@ -15,24 +15,24 @@ pub fn decode(s string) ?[]u8 {
|
||||||
if hex_str.len == 0 {
|
if hex_str.len == 0 {
|
||||||
return []u8{}
|
return []u8{}
|
||||||
} else if hex_str.len == 1 {
|
} else if hex_str.len == 1 {
|
||||||
return [char2nibble(hex_str[0])?]
|
return [char2nibble(hex_str[0])!]
|
||||||
} else if hex_str.len == 2 {
|
} else if hex_str.len == 2 {
|
||||||
n1 := char2nibble(hex_str[0])?
|
n1 := char2nibble(hex_str[0])!
|
||||||
n0 := char2nibble(hex_str[1])?
|
n0 := char2nibble(hex_str[1])!
|
||||||
return [(n1 << 4) | n0]
|
return [(n1 << 4) | n0]
|
||||||
}
|
}
|
||||||
// calculate the first byte depending on if hex_str.len is odd
|
// calculate the first byte depending on if hex_str.len is odd
|
||||||
mut val := char2nibble(hex_str[0])?
|
mut val := char2nibble(hex_str[0])!
|
||||||
if hex_str.len & 1 == 0 {
|
if hex_str.len & 1 == 0 {
|
||||||
val = (val << 4) | char2nibble(hex_str[1])?
|
val = (val << 4) | char2nibble(hex_str[1])!
|
||||||
}
|
}
|
||||||
// set cap to hex_str.len/2 rounded up
|
// set cap to hex_str.len/2 rounded up
|
||||||
mut bytes := []u8{len: 1, cap: (hex_str.len + 1) >> 1, init: val}
|
mut bytes := []u8{len: 1, cap: (hex_str.len + 1) >> 1, init: val}
|
||||||
// iterate over every 2 bytes
|
// iterate over every 2 bytes
|
||||||
// the start index depends on if hex_str.len is odd
|
// the start index depends on if hex_str.len is odd
|
||||||
for i := 2 - (hex_str.len & 1); i < hex_str.len; i += 2 {
|
for i := 2 - (hex_str.len & 1); i < hex_str.len; i += 2 {
|
||||||
n1 := char2nibble(hex_str[i])?
|
n1 := char2nibble(hex_str[i])!
|
||||||
n0 := char2nibble(hex_str[i + 1])?
|
n0 := char2nibble(hex_str[i + 1])!
|
||||||
bytes << (n1 << 4) | n0
|
bytes << (n1 << 4) | n0
|
||||||
}
|
}
|
||||||
return bytes
|
return bytes
|
||||||
|
@ -52,7 +52,7 @@ pub fn encode(bytes []u8) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// char2nibble converts an ASCII hex character to it's hex value
|
// char2nibble converts an ASCII hex character to it's hex value
|
||||||
fn char2nibble(b u8) ?u8 {
|
fn char2nibble(b u8) !u8 {
|
||||||
match b {
|
match b {
|
||||||
`0`...`9` { return b - u8(`0`) }
|
`0`...`9` { return b - u8(`0`) }
|
||||||
`A`...`F` { return b - u8(`A`) + 10 }
|
`A`...`F` { return b - u8(`A`) + 10 }
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
module hex
|
module hex
|
||||||
|
|
||||||
fn test_decode() ? {
|
fn test_decode() {
|
||||||
assert decode('')? == []
|
assert decode('')! == []
|
||||||
assert decode('0')? == [u8(0x0)]
|
assert decode('0')! == [u8(0x0)]
|
||||||
assert decode('f')? == [u8(0xf)]
|
assert decode('f')! == [u8(0xf)]
|
||||||
assert decode('0f')? == [u8(0x0f)]
|
assert decode('0f')! == [u8(0x0f)]
|
||||||
assert decode('ff')? == [u8(0xff)]
|
assert decode('ff')! == [u8(0xff)]
|
||||||
assert decode('123')? == [u8(0x1), 0x23]
|
assert decode('123')! == [u8(0x1), 0x23]
|
||||||
assert decode('1234')? == [u8(0x12), 0x34]
|
assert decode('1234')! == [u8(0x12), 0x34]
|
||||||
assert decode('12345')? == [u8(0x1), 0x23, 0x45]
|
assert decode('12345')! == [u8(0x1), 0x23, 0x45]
|
||||||
assert decode('0123456789abcdef')? == [u8(0x01), 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]
|
assert decode('0123456789abcdef')! == [u8(0x01), 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]
|
||||||
assert decode('123456789ABCDEF')? == [u8(0x01), 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]
|
assert decode('123456789ABCDEF')! == [u8(0x01), 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_decode_fails() ? {
|
fn test_decode_fails() ! {
|
||||||
if x := decode('foo') {
|
if x := decode('foo') {
|
||||||
return error('expected decode to fail, got $x')
|
return error('expected decode to fail, got $x')
|
||||||
}
|
}
|
||||||
|
@ -31,24 +31,24 @@ fn test_decode_fails() ? {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_encode() ? {
|
fn test_encode() {
|
||||||
assert encode(decode('')?) == ''
|
assert encode(decode('')!) == ''
|
||||||
assert encode(decode('0')?) == '00'
|
assert encode(decode('0')!) == '00'
|
||||||
assert encode(decode('f')?) == '0f'
|
assert encode(decode('f')!) == '0f'
|
||||||
assert encode(decode('0f')?) == '0f'
|
assert encode(decode('0f')!) == '0f'
|
||||||
assert encode(decode('ff')?) == 'ff'
|
assert encode(decode('ff')!) == 'ff'
|
||||||
assert encode(decode('123')?) == '0123'
|
assert encode(decode('123')!) == '0123'
|
||||||
assert encode(decode('1234')?) == '1234'
|
assert encode(decode('1234')!) == '1234'
|
||||||
assert encode(decode('12345')?) == '012345'
|
assert encode(decode('12345')!) == '012345'
|
||||||
assert encode(decode('abcdef')?) == 'abcdef'
|
assert encode(decode('abcdef')!) == 'abcdef'
|
||||||
assert encode(decode('ABCDEF')?) == 'abcdef'
|
assert encode(decode('ABCDEF')!) == 'abcdef'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_decode_0x() ? {
|
fn test_decode_0x() {
|
||||||
assert decode('0x')? == []
|
assert decode('0x')! == []
|
||||||
assert decode('0x0')? == [u8(0x0)]
|
assert decode('0x0')! == [u8(0x0)]
|
||||||
assert decode('0X1234')? == [u8(0x12), 0x34]
|
assert decode('0X1234')! == [u8(0x12), 0x34]
|
||||||
assert decode('0x12345')? == [u8(0x1), 0x23, 0x45]
|
assert decode('0x12345')! == [u8(0x1), 0x23, 0x45]
|
||||||
assert decode('0x0123456789abcdef')? == [u8(0x01), 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]
|
assert decode('0x0123456789abcdef')! == [u8(0x01), 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]
|
||||||
assert decode('0X123456789ABCDEF')? == [u8(0x01), 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]
|
assert decode('0X123456789ABCDEF')! == [u8(0x01), 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,17 +154,17 @@ pub fn integer_from_bytes(input []u8, config IntegerConfig) Integer {
|
||||||
|
|
||||||
// integer_from_string creates a new `big.Integer` from the decimal digits specified in the given string.
|
// integer_from_string creates a new `big.Integer` from the decimal digits specified in the given string.
|
||||||
// For other bases, use `big.integer_from_radix` instead.
|
// For other bases, use `big.integer_from_radix` instead.
|
||||||
pub fn integer_from_string(characters string) ?Integer {
|
pub fn integer_from_string(characters string) !Integer {
|
||||||
return integer_from_radix(characters, 10)
|
return integer_from_radix(characters, 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
// integer_from_radix creates a new `big.Integer` from the given string and radix.
|
// integer_from_radix creates a new `big.Integer` from the given string and radix.
|
||||||
pub fn integer_from_radix(all_characters string, radix u32) ?Integer {
|
pub fn integer_from_radix(all_characters string, radix u32) !Integer {
|
||||||
if radix < 2 || radix > 36 {
|
if radix < 2 || radix > 36 {
|
||||||
return error('Radix must be between 2 and 36 (inclusive)')
|
return error('Radix must be between 2 and 36 (inclusive)')
|
||||||
}
|
}
|
||||||
characters := all_characters.to_lower()
|
characters := all_characters.to_lower()
|
||||||
validate_string(characters, radix)?
|
validate_string(characters, radix)!
|
||||||
return match radix {
|
return match radix {
|
||||||
2 {
|
2 {
|
||||||
integer_from_special_string(characters, 1)
|
integer_from_special_string(characters, 1)
|
||||||
|
@ -179,7 +179,7 @@ pub fn integer_from_radix(all_characters string, radix u32) ?Integer {
|
||||||
}
|
}
|
||||||
|
|
||||||
[direct_array_access]
|
[direct_array_access]
|
||||||
fn validate_string(characters string, radix u32) ? {
|
fn validate_string(characters string, radix u32) ! {
|
||||||
sign_present := characters[0] == `+` || characters[0] == `-`
|
sign_present := characters[0] == `+` || characters[0] == `-`
|
||||||
|
|
||||||
start_index := if sign_present { 1 } else { 0 }
|
start_index := if sign_present { 1 } else { 0 }
|
||||||
|
|
|
@ -16,7 +16,7 @@ rand.seed([u32(3110), 50714])
|
||||||
...
|
...
|
||||||
|
|
||||||
// Use the top-level functions
|
// Use the top-level functions
|
||||||
rand.u32n(100)?
|
rand.u32n(100)!
|
||||||
rand.int() // among others ...
|
rand.int() // among others ...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ rng.seed(seed.time_seed_array(pcg32.seed_len))
|
||||||
...
|
...
|
||||||
|
|
||||||
// Use functions of your choice
|
// Use functions of your choice
|
||||||
rng.u32n(100)?
|
rng.u32n(100)!
|
||||||
rng.int() // among others ...
|
rng.int() // among others ...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ pub:
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate_for is a helper function for validating the configuration struct for the given array.
|
// validate_for is a helper function for validating the configuration struct for the given array.
|
||||||
pub fn (config ShuffleConfigStruct) validate_for<T>(a []T) ? {
|
pub fn (config ShuffleConfigStruct) validate_for<T>(a []T) ! {
|
||||||
if config.start < 0 || config.start >= a.len {
|
if config.start < 0 || config.start >= a.len {
|
||||||
return error("argument 'config.start' must be in range [0, a.len)")
|
return error("argument 'config.start' must be in range [0, a.len)")
|
||||||
}
|
}
|
||||||
|
|
110
vlib/rand/rand.v
110
vlib/rand/rand.v
|
@ -26,7 +26,7 @@ mut:
|
||||||
|
|
||||||
// bytes returns a buffer of `bytes_needed` random bytes
|
// bytes returns a buffer of `bytes_needed` random bytes
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut rng PRNG) bytes(bytes_needed int) ?[]u8 {
|
pub fn (mut rng PRNG) bytes(bytes_needed int) ![]u8 {
|
||||||
if bytes_needed < 0 {
|
if bytes_needed < 0 {
|
||||||
return error('can not read < 0 random bytes')
|
return error('can not read < 0 random bytes')
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ pub fn (mut rng PRNG) read(mut buf []u8) {
|
||||||
|
|
||||||
// u32n returns a uniformly distributed pseudorandom 32-bit signed positive `u32` in range `[0, max)`.
|
// u32n returns a uniformly distributed pseudorandom 32-bit signed positive `u32` in range `[0, max)`.
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut rng PRNG) u32n(max u32) ?u32 {
|
pub fn (mut rng PRNG) u32n(max u32) !u32 {
|
||||||
if max == 0 {
|
if max == 0 {
|
||||||
return error('max must be positive integer')
|
return error('max must be positive integer')
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ pub fn (mut rng PRNG) u32n(max u32) ?u32 {
|
||||||
|
|
||||||
// u64n returns a uniformly distributed pseudorandom 64-bit signed positive `u64` in range `[0, max)`.
|
// u64n returns a uniformly distributed pseudorandom 64-bit signed positive `u64` in range `[0, max)`.
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut rng PRNG) u64n(max u64) ?u64 {
|
pub fn (mut rng PRNG) u64n(max u64) !u64 {
|
||||||
if max == 0 {
|
if max == 0 {
|
||||||
return error('max must be positive integer')
|
return error('max must be positive integer')
|
||||||
}
|
}
|
||||||
|
@ -102,20 +102,20 @@ pub fn (mut rng PRNG) u64n(max u64) ?u64 {
|
||||||
|
|
||||||
// u32_in_range returns a uniformly distributed pseudorandom 32-bit unsigned `u32` in range `[min, max)`.
|
// u32_in_range returns a uniformly distributed pseudorandom 32-bit unsigned `u32` in range `[min, max)`.
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut rng PRNG) u32_in_range(min u32, max u32) ?u32 {
|
pub fn (mut rng PRNG) u32_in_range(min u32, max u32) !u32 {
|
||||||
if max <= min {
|
if max <= min {
|
||||||
return error('max must be greater than min')
|
return error('max must be greater than min')
|
||||||
}
|
}
|
||||||
return min + rng.u32n(max - min)?
|
return min + rng.u32n(max - min)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// u64_in_range returns a uniformly distributed pseudorandom 64-bit unsigned `u64` in range `[min, max)`.
|
// u64_in_range returns a uniformly distributed pseudorandom 64-bit unsigned `u64` in range `[min, max)`.
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut rng PRNG) u64_in_range(min u64, max u64) ?u64 {
|
pub fn (mut rng PRNG) u64_in_range(min u64, max u64) !u64 {
|
||||||
if max <= min {
|
if max <= min {
|
||||||
return error('max must be greater than min')
|
return error('max must be greater than min')
|
||||||
}
|
}
|
||||||
return min + rng.u64n(max - min)?
|
return min + rng.u64n(max - min)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// i8 returns a (possibly negative) pseudorandom 8-bit `i8`.
|
// i8 returns a (possibly negative) pseudorandom 8-bit `i8`.
|
||||||
|
@ -156,39 +156,39 @@ pub fn (mut rng PRNG) int63() i64 {
|
||||||
|
|
||||||
// intn returns a pseudorandom `int` in range `[0, max)`.
|
// intn returns a pseudorandom `int` in range `[0, max)`.
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut rng PRNG) intn(max int) ?int {
|
pub fn (mut rng PRNG) intn(max int) !int {
|
||||||
if max <= 0 {
|
if max <= 0 {
|
||||||
return error('max has to be positive.')
|
return error('max has to be positive.')
|
||||||
}
|
}
|
||||||
return int(rng.u32n(u32(max))?)
|
return int(rng.u32n(u32(max))!)
|
||||||
}
|
}
|
||||||
|
|
||||||
// i64n returns a pseudorandom int that lies in `[0, max)`.
|
// i64n returns a pseudorandom int that lies in `[0, max)`.
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut rng PRNG) i64n(max i64) ?i64 {
|
pub fn (mut rng PRNG) i64n(max i64) !i64 {
|
||||||
if max <= 0 {
|
if max <= 0 {
|
||||||
return error('max has to be positive.')
|
return error('max has to be positive.')
|
||||||
}
|
}
|
||||||
return i64(rng.u64n(u64(max))?)
|
return i64(rng.u64n(u64(max))!)
|
||||||
}
|
}
|
||||||
|
|
||||||
// int_in_range returns a pseudorandom `int` in range `[min, max)`.
|
// int_in_range returns a pseudorandom `int` in range `[min, max)`.
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut rng PRNG) int_in_range(min int, max int) ?int {
|
pub fn (mut rng PRNG) int_in_range(min int, max int) !int {
|
||||||
if max <= min {
|
if max <= min {
|
||||||
return error('max must be greater than min')
|
return error('max must be greater than min')
|
||||||
}
|
}
|
||||||
// This supports negative ranges like [-10, -5) because the difference is positive
|
// This supports negative ranges like [-10, -5) because the difference is positive
|
||||||
return min + rng.intn(max - min)?
|
return min + rng.intn(max - min)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// i64_in_range returns a pseudorandom `i64` in range `[min, max)`.
|
// i64_in_range returns a pseudorandom `i64` in range `[min, max)`.
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut rng PRNG) i64_in_range(min i64, max i64) ?i64 {
|
pub fn (mut rng PRNG) i64_in_range(min i64, max i64) !i64 {
|
||||||
if max <= min {
|
if max <= min {
|
||||||
return error('max must be greater than min')
|
return error('max must be greater than min')
|
||||||
}
|
}
|
||||||
return min + rng.i64n(max - min)?
|
return min + rng.i64n(max - min)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// f32 returns a pseudorandom `f32` value in range `[0, 1)`.
|
// f32 returns a pseudorandom `f32` value in range `[0, 1)`.
|
||||||
|
@ -205,7 +205,7 @@ pub fn (mut rng PRNG) f64() f64 {
|
||||||
|
|
||||||
// f32n returns a pseudorandom `f32` value in range `[0, max]`.
|
// f32n returns a pseudorandom `f32` value in range `[0, max]`.
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut rng PRNG) f32n(max f32) ?f32 {
|
pub fn (mut rng PRNG) f32n(max f32) !f32 {
|
||||||
if max < 0 {
|
if max < 0 {
|
||||||
return error('max has to be non-negative.')
|
return error('max has to be non-negative.')
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ pub fn (mut rng PRNG) f32n(max f32) ?f32 {
|
||||||
|
|
||||||
// f64n returns a pseudorandom `f64` value in range `[0, max]`.
|
// f64n returns a pseudorandom `f64` value in range `[0, max]`.
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut rng PRNG) f64n(max f64) ?f64 {
|
pub fn (mut rng PRNG) f64n(max f64) !f64 {
|
||||||
if max < 0 {
|
if max < 0 {
|
||||||
return error('max has to be non-negative.')
|
return error('max has to be non-negative.')
|
||||||
}
|
}
|
||||||
|
@ -223,20 +223,20 @@ pub fn (mut rng PRNG) f64n(max f64) ?f64 {
|
||||||
|
|
||||||
// f32_in_range returns a pseudorandom `f32` in range `[min, max]`.
|
// f32_in_range returns a pseudorandom `f32` in range `[min, max]`.
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut rng PRNG) f32_in_range(min f32, max f32) ?f32 {
|
pub fn (mut rng PRNG) f32_in_range(min f32, max f32) !f32 {
|
||||||
if max < min {
|
if max < min {
|
||||||
return error('max must be greater than or equal to min')
|
return error('max must be greater than or equal to min')
|
||||||
}
|
}
|
||||||
return min + rng.f32n(max - min)?
|
return min + rng.f32n(max - min)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// i64_in_range returns a pseudorandom `i64` in range `[min, max]`.
|
// i64_in_range returns a pseudorandom `i64` in range `[min, max]`.
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (mut rng PRNG) f64_in_range(min f64, max f64) ?f64 {
|
pub fn (mut rng PRNG) f64_in_range(min f64, max f64) !f64 {
|
||||||
if max < min {
|
if max < min {
|
||||||
return error('max must be greater than or equal to min')
|
return error('max must be greater than or equal to min')
|
||||||
}
|
}
|
||||||
return min + rng.f64n(max - min)?
|
return min + rng.f64n(max - min)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// ulid generates an Unique Lexicographically sortable IDentifier.
|
// ulid generates an Unique Lexicographically sortable IDentifier.
|
||||||
|
@ -275,7 +275,7 @@ pub fn (mut rng PRNG) ascii(len int) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// bernoulli returns true with a probability p. Note that 0 <= p <= 1.
|
// bernoulli returns true with a probability p. Note that 0 <= p <= 1.
|
||||||
pub fn (mut rng PRNG) bernoulli(p f64) ?bool {
|
pub fn (mut rng PRNG) bernoulli(p f64) !bool {
|
||||||
if p < 0 || p > 1 {
|
if p < 0 || p > 1 {
|
||||||
return error('$p is not a valid probability value.')
|
return error('$p is not a valid probability value.')
|
||||||
}
|
}
|
||||||
|
@ -284,13 +284,13 @@ pub fn (mut rng PRNG) bernoulli(p f64) ?bool {
|
||||||
|
|
||||||
// normal returns a normally distributed pseudorandom f64 in range `[0, 1)`.
|
// normal returns a normally distributed pseudorandom f64 in range `[0, 1)`.
|
||||||
// NOTE: Use normal_pair() instead if you're generating a lot of normal variates.
|
// NOTE: Use normal_pair() instead if you're generating a lot of normal variates.
|
||||||
pub fn (mut rng PRNG) normal(conf config.NormalConfigStruct) ?f64 {
|
pub fn (mut rng PRNG) normal(conf config.NormalConfigStruct) !f64 {
|
||||||
x, _ := rng.normal_pair(conf)?
|
x, _ := rng.normal_pair(conf)!
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
// normal_pair returns a pair of normally distributed pseudorandom f64 in range `[0, 1)`.
|
// normal_pair returns a pair of normally distributed pseudorandom f64 in range `[0, 1)`.
|
||||||
pub fn (mut rng PRNG) normal_pair(conf config.NormalConfigStruct) ?(f64, f64) {
|
pub fn (mut rng PRNG) normal_pair(conf config.NormalConfigStruct) !(f64, f64) {
|
||||||
if conf.sigma <= 0 {
|
if conf.sigma <= 0 {
|
||||||
return error('Standard deviation must be positive')
|
return error('Standard deviation must be positive')
|
||||||
}
|
}
|
||||||
|
@ -315,7 +315,7 @@ pub fn (mut rng PRNG) normal_pair(conf config.NormalConfigStruct) ?(f64, f64) {
|
||||||
|
|
||||||
// binomial returns the number of successful trials out of n when the
|
// binomial returns the number of successful trials out of n when the
|
||||||
// probability of success for each trial is p.
|
// probability of success for each trial is p.
|
||||||
pub fn (mut rng PRNG) binomial(n int, p f64) ?int {
|
pub fn (mut rng PRNG) binomial(n int, p f64) !int {
|
||||||
if p < 0 || p > 1 {
|
if p < 0 || p > 1 {
|
||||||
return error('$p is not a valid probability value.')
|
return error('$p is not a valid probability value.')
|
||||||
}
|
}
|
||||||
|
@ -342,8 +342,8 @@ pub fn (mut rng PRNG) exponential(lambda f64) f64 {
|
||||||
// optional and the entire array is shuffled by default. Leave the end as 0 to
|
// optional and the entire array is shuffled by default. Leave the end as 0 to
|
||||||
// shuffle all elements until the end.
|
// shuffle all elements until the end.
|
||||||
[direct_array_access]
|
[direct_array_access]
|
||||||
pub fn (mut rng PRNG) shuffle<T>(mut a []T, config config.ShuffleConfigStruct) ? {
|
pub fn (mut rng PRNG) shuffle<T>(mut a []T, config config.ShuffleConfigStruct) ! {
|
||||||
config.validate_for(a)?
|
config.validate_for(a)!
|
||||||
new_end := if config.end == 0 { a.len } else { config.end }
|
new_end := if config.end == 0 { a.len } else { config.end }
|
||||||
|
|
||||||
// We implement the Fisher-Yates shuffle:
|
// We implement the Fisher-Yates shuffle:
|
||||||
|
@ -360,23 +360,23 @@ pub fn (mut rng PRNG) shuffle<T>(mut a []T, config config.ShuffleConfigStruct) ?
|
||||||
|
|
||||||
// shuffle_clone returns a random permutation of the elements in `a`.
|
// shuffle_clone returns a random permutation of the elements in `a`.
|
||||||
// The permutation is done on a fresh clone of `a`, so `a` remains unchanged.
|
// The permutation is done on a fresh clone of `a`, so `a` remains unchanged.
|
||||||
pub fn (mut rng PRNG) shuffle_clone<T>(a []T, config config.ShuffleConfigStruct) ?[]T {
|
pub fn (mut rng PRNG) shuffle_clone<T>(a []T, config config.ShuffleConfigStruct) ![]T {
|
||||||
mut res := a.clone()
|
mut res := a.clone()
|
||||||
rng.shuffle<T>(mut res, config)?
|
rng.shuffle<T>(mut res, config)!
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// choose samples k elements from the array without replacement.
|
// choose samples k elements from the array without replacement.
|
||||||
// This means the indices cannot repeat and it restricts the sample size to be less than or equal to the size of the given array.
|
// This means the indices cannot repeat and it restricts the sample size to be less than or equal to the size of the given array.
|
||||||
// Note that if the array has repeating elements, then the sample may have repeats as well.
|
// Note that if the array has repeating elements, then the sample may have repeats as well.
|
||||||
pub fn (mut rng PRNG) choose<T>(array []T, k int) ?[]T {
|
pub fn (mut rng PRNG) choose<T>(array []T, k int) ![]T {
|
||||||
n := array.len
|
n := array.len
|
||||||
if k > n {
|
if k > n {
|
||||||
return error('Cannot choose $k elements without replacement from a $n-element array.')
|
return error('Cannot choose $k elements without replacement from a $n-element array.')
|
||||||
}
|
}
|
||||||
mut results := []T{len: k}
|
mut results := []T{len: k}
|
||||||
mut indices := []int{len: n, init: it}
|
mut indices := []int{len: n, init: it}
|
||||||
rng.shuffle<int>(mut indices)?
|
rng.shuffle<int>(mut indices)!
|
||||||
for i in 0 .. k {
|
for i in 0 .. k {
|
||||||
results[i] = array[indices[i]]
|
results[i] = array[indices[i]]
|
||||||
}
|
}
|
||||||
|
@ -385,7 +385,7 @@ pub fn (mut rng PRNG) choose<T>(array []T, k int) ?[]T {
|
||||||
|
|
||||||
// element returns a random element from the given array.
|
// element returns a random element from the given array.
|
||||||
// Note that all the positions in the array have an equal chance of being selected. This means that if the array has repeating elements, then the probability of selecting a particular element is not uniform.
|
// Note that all the positions in the array have an equal chance of being selected. This means that if the array has repeating elements, then the probability of selecting a particular element is not uniform.
|
||||||
pub fn (mut rng PRNG) element<T>(array []T) ?T {
|
pub fn (mut rng PRNG) element<T>(array []T) !T {
|
||||||
if array.len == 0 {
|
if array.len == 0 {
|
||||||
return error('Cannot choose an element from an empty array.')
|
return error('Cannot choose an element from an empty array.')
|
||||||
}
|
}
|
||||||
|
@ -445,22 +445,22 @@ pub fn u64() u64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// u32n returns a uniformly distributed pseudorandom 32-bit signed positive `u32` in range `[0, max)`.
|
// u32n returns a uniformly distributed pseudorandom 32-bit signed positive `u32` in range `[0, max)`.
|
||||||
pub fn u32n(max u32) ?u32 {
|
pub fn u32n(max u32) !u32 {
|
||||||
return default_rng.u32n(max)
|
return default_rng.u32n(max)
|
||||||
}
|
}
|
||||||
|
|
||||||
// u64n returns a uniformly distributed pseudorandom 64-bit signed positive `u64` in range `[0, max)`.
|
// u64n returns a uniformly distributed pseudorandom 64-bit signed positive `u64` in range `[0, max)`.
|
||||||
pub fn u64n(max u64) ?u64 {
|
pub fn u64n(max u64) !u64 {
|
||||||
return default_rng.u64n(max)
|
return default_rng.u64n(max)
|
||||||
}
|
}
|
||||||
|
|
||||||
// u32_in_range returns a uniformly distributed pseudorandom 32-bit unsigned `u32` in range `[min, max)`.
|
// u32_in_range returns a uniformly distributed pseudorandom 32-bit unsigned `u32` in range `[min, max)`.
|
||||||
pub fn u32_in_range(min u32, max u32) ?u32 {
|
pub fn u32_in_range(min u32, max u32) !u32 {
|
||||||
return default_rng.u32_in_range(min, max)
|
return default_rng.u32_in_range(min, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
// u64_in_range returns a uniformly distributed pseudorandom 64-bit unsigned `u64` in range `[min, max)`.
|
// u64_in_range returns a uniformly distributed pseudorandom 64-bit unsigned `u64` in range `[min, max)`.
|
||||||
pub fn u64_in_range(min u64, max u64) ?u64 {
|
pub fn u64_in_range(min u64, max u64) !u64 {
|
||||||
return default_rng.u64_in_range(min, max)
|
return default_rng.u64_in_range(min, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,7 +475,7 @@ pub fn int() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// intn returns a uniformly distributed pseudorandom 32-bit signed positive `int` in range `[0, max)`.
|
// intn returns a uniformly distributed pseudorandom 32-bit signed positive `int` in range `[0, max)`.
|
||||||
pub fn intn(max int) ?int {
|
pub fn intn(max int) !int {
|
||||||
return default_rng.intn(max)
|
return default_rng.intn(max)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,7 +486,7 @@ pub fn u8() u8 {
|
||||||
|
|
||||||
// int_in_range returns a uniformly distributed pseudorandom 32-bit signed int in range `[min, max)`.
|
// int_in_range returns a uniformly distributed pseudorandom 32-bit signed int in range `[min, max)`.
|
||||||
// Both `min` and `max` can be negative, but we must have `min < max`.
|
// Both `min` and `max` can be negative, but we must have `min < max`.
|
||||||
pub fn int_in_range(min int, max int) ?int {
|
pub fn int_in_range(min int, max int) !int {
|
||||||
return default_rng.int_in_range(min, max)
|
return default_rng.int_in_range(min, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,12 +501,12 @@ pub fn i64() i64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// i64n returns a uniformly distributed pseudorandom 64-bit signed positive `i64` in range `[0, max)`.
|
// i64n returns a uniformly distributed pseudorandom 64-bit signed positive `i64` in range `[0, max)`.
|
||||||
pub fn i64n(max i64) ?i64 {
|
pub fn i64n(max i64) !i64 {
|
||||||
return default_rng.i64n(max)
|
return default_rng.i64n(max)
|
||||||
}
|
}
|
||||||
|
|
||||||
// i64_in_range returns a uniformly distributed pseudorandom 64-bit signed `i64` in range `[min, max)`.
|
// i64_in_range returns a uniformly distributed pseudorandom 64-bit signed `i64` in range `[min, max)`.
|
||||||
pub fn i64_in_range(min i64, max i64) ?i64 {
|
pub fn i64_in_range(min i64, max i64) !i64 {
|
||||||
return default_rng.i64_in_range(min, max)
|
return default_rng.i64_in_range(min, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -526,27 +526,27 @@ pub fn f64() f64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// f32n returns a uniformly distributed 32-bit floating point in range `[0, max)`.
|
// f32n returns a uniformly distributed 32-bit floating point in range `[0, max)`.
|
||||||
pub fn f32n(max f32) ?f32 {
|
pub fn f32n(max f32) !f32 {
|
||||||
return default_rng.f32n(max)
|
return default_rng.f32n(max)
|
||||||
}
|
}
|
||||||
|
|
||||||
// f64n returns a uniformly distributed 64-bit floating point in range `[0, max)`.
|
// f64n returns a uniformly distributed 64-bit floating point in range `[0, max)`.
|
||||||
pub fn f64n(max f64) ?f64 {
|
pub fn f64n(max f64) !f64 {
|
||||||
return default_rng.f64n(max)
|
return default_rng.f64n(max)
|
||||||
}
|
}
|
||||||
|
|
||||||
// f32_in_range returns a uniformly distributed 32-bit floating point in range `[min, max)`.
|
// f32_in_range returns a uniformly distributed 32-bit floating point in range `[min, max)`.
|
||||||
pub fn f32_in_range(min f32, max f32) ?f32 {
|
pub fn f32_in_range(min f32, max f32) !f32 {
|
||||||
return default_rng.f32_in_range(min, max)
|
return default_rng.f32_in_range(min, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
// f64_in_range returns a uniformly distributed 64-bit floating point in range `[min, max)`.
|
// f64_in_range returns a uniformly distributed 64-bit floating point in range `[min, max)`.
|
||||||
pub fn f64_in_range(min f64, max f64) ?f64 {
|
pub fn f64_in_range(min f64, max f64) !f64 {
|
||||||
return default_rng.f64_in_range(min, max)
|
return default_rng.f64_in_range(min, max)
|
||||||
}
|
}
|
||||||
|
|
||||||
// bytes returns a buffer of `bytes_needed` random bytes
|
// bytes returns a buffer of `bytes_needed` random bytes
|
||||||
pub fn bytes(bytes_needed int) ?[]u8 {
|
pub fn bytes(bytes_needed int) ![]u8 {
|
||||||
return default_rng.bytes(bytes_needed)
|
return default_rng.bytes(bytes_needed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,26 +599,26 @@ pub fn ascii(len int) string {
|
||||||
// shuffle randomly permutates the elements in `a`. The range for shuffling is
|
// shuffle randomly permutates the elements in `a`. The range for shuffling is
|
||||||
// optional and the entire array is shuffled by default. Leave the end as 0 to
|
// optional and the entire array is shuffled by default. Leave the end as 0 to
|
||||||
// shuffle all elements until the end.
|
// shuffle all elements until the end.
|
||||||
pub fn shuffle<T>(mut a []T, config config.ShuffleConfigStruct) ? {
|
pub fn shuffle<T>(mut a []T, config config.ShuffleConfigStruct) ! {
|
||||||
default_rng.shuffle<T>(mut a, config)?
|
default_rng.shuffle<T>(mut a, config)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// shuffle_clone returns a random permutation of the elements in `a`.
|
// shuffle_clone returns a random permutation of the elements in `a`.
|
||||||
// The permutation is done on a fresh clone of `a`, so `a` remains unchanged.
|
// The permutation is done on a fresh clone of `a`, so `a` remains unchanged.
|
||||||
pub fn shuffle_clone<T>(a []T, config config.ShuffleConfigStruct) ?[]T {
|
pub fn shuffle_clone<T>(a []T, config config.ShuffleConfigStruct) ![]T {
|
||||||
return default_rng.shuffle_clone<T>(a, config)
|
return default_rng.shuffle_clone<T>(a, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// choose samples k elements from the array without replacement.
|
// choose samples k elements from the array without replacement.
|
||||||
// This means the indices cannot repeat and it restricts the sample size to be less than or equal to the size of the given array.
|
// This means the indices cannot repeat and it restricts the sample size to be less than or equal to the size of the given array.
|
||||||
// Note that if the array has repeating elements, then the sample may have repeats as well.
|
// Note that if the array has repeating elements, then the sample may have repeats as well.
|
||||||
pub fn choose<T>(array []T, k int) ?[]T {
|
pub fn choose<T>(array []T, k int) ![]T {
|
||||||
return default_rng.choose<T>(array, k)
|
return default_rng.choose<T>(array, k)
|
||||||
}
|
}
|
||||||
|
|
||||||
// element returns a random element from the given array.
|
// element returns a random element from the given array.
|
||||||
// Note that all the positions in the array have an equal chance of being selected. This means that if the array has repeating elements, then the probability of selecting a particular element is not uniform.
|
// Note that all the positions in the array have an equal chance of being selected. This means that if the array has repeating elements, then the probability of selecting a particular element is not uniform.
|
||||||
pub fn element<T>(array []T) ?T {
|
pub fn element<T>(array []T) !T {
|
||||||
return default_rng.element<T>(array)
|
return default_rng.element<T>(array)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,24 +629,24 @@ pub fn sample<T>(array []T, k int) []T {
|
||||||
}
|
}
|
||||||
|
|
||||||
// bernoulli returns true with a probability p. Note that 0 <= p <= 1.
|
// bernoulli returns true with a probability p. Note that 0 <= p <= 1.
|
||||||
pub fn bernoulli(p f64) ?bool {
|
pub fn bernoulli(p f64) !bool {
|
||||||
return default_rng.bernoulli(p)
|
return default_rng.bernoulli(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// normal returns a normally distributed pseudorandom f64 in range `[0, 1)`.
|
// normal returns a normally distributed pseudorandom f64 in range `[0, 1)`.
|
||||||
// NOTE: Use normal_pair() instead if you're generating a lot of normal variates.
|
// NOTE: Use normal_pair() instead if you're generating a lot of normal variates.
|
||||||
pub fn normal(conf config.NormalConfigStruct) ?f64 {
|
pub fn normal(conf config.NormalConfigStruct) !f64 {
|
||||||
return default_rng.normal(conf)
|
return default_rng.normal(conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// normal_pair returns a pair of normally distributed pseudorandom f64 in range `[0, 1)`.
|
// normal_pair returns a pair of normally distributed pseudorandom f64 in range `[0, 1)`.
|
||||||
pub fn normal_pair(conf config.NormalConfigStruct) ?(f64, f64) {
|
pub fn normal_pair(conf config.NormalConfigStruct) !(f64, f64) {
|
||||||
return default_rng.normal_pair(conf)
|
return default_rng.normal_pair(conf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// binomial returns the number of successful trials out of n when the
|
// binomial returns the number of successful trials out of n when the
|
||||||
// probability of success for each trial is p.
|
// probability of success for each trial is p.
|
||||||
pub fn binomial(n int, p f64) ?int {
|
pub fn binomial(n int, p f64) !int {
|
||||||
return default_rng.binomial(n, p)
|
return default_rng.binomial(n, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import rand
|
||||||
fn test_rand_bytes() {
|
fn test_rand_bytes() {
|
||||||
mut randoms := []string{}
|
mut randoms := []string{}
|
||||||
for i in 0 .. 100 {
|
for i in 0 .. 100 {
|
||||||
x := rand.bytes(i)?.hex()
|
x := rand.bytes(i)!.hex()
|
||||||
if x.len > 0 {
|
if x.len > 0 {
|
||||||
randoms << x
|
randoms << x
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ fn test_prng_rand_bytes() {
|
||||||
mut randoms := []string{}
|
mut randoms := []string{}
|
||||||
mut rng := rand.get_current_rng()
|
mut rng := rand.get_current_rng()
|
||||||
for i in 0 .. 100 {
|
for i in 0 .. 100 {
|
||||||
x := rng.bytes(i)?.hex()
|
x := rng.bytes(i)!.hex()
|
||||||
if x.len > 0 {
|
if x.len > 0 {
|
||||||
randoms << x
|
randoms << x
|
||||||
}
|
}
|
||||||
|
|
|
@ -358,11 +358,11 @@ fn test_shuffle_partial() {
|
||||||
mut a := [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
mut a := [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||||
mut b := a.clone()
|
mut b := a.clone()
|
||||||
|
|
||||||
rand.shuffle(mut a, start: 4)?
|
rand.shuffle(mut a, start: 4)!
|
||||||
assert a[..4] == b[..4]
|
assert a[..4] == b[..4]
|
||||||
|
|
||||||
a = b.clone()
|
a = b.clone()
|
||||||
rand.shuffle(mut a, start: 3, end: 7)?
|
rand.shuffle(mut a, start: 3, end: 7)!
|
||||||
assert a[..3] == b[..3]
|
assert a[..3] == b[..3]
|
||||||
assert a[7..] == b[7..]
|
assert a[7..] == b[7..]
|
||||||
}
|
}
|
||||||
|
@ -386,7 +386,7 @@ fn test_choose() {
|
||||||
lengths := [1, 3, 4, 5, 6, 7]
|
lengths := [1, 3, 4, 5, 6, 7]
|
||||||
a := ['one', 'two', 'three', 'four', 'five', 'six', 'seven']
|
a := ['one', 'two', 'three', 'four', 'five', 'six', 'seven']
|
||||||
for length in lengths {
|
for length in lengths {
|
||||||
b := rand.choose(a, length)?
|
b := rand.choose(a, length)!
|
||||||
assert b.len == length
|
assert b.len == length
|
||||||
for element in b {
|
for element in b {
|
||||||
assert element in a
|
assert element in a
|
||||||
|
@ -415,7 +415,7 @@ fn test_sample() {
|
||||||
fn test_element1() {
|
fn test_element1() {
|
||||||
a := ['one', 'two', 'four', 'five', 'six', 'seven']
|
a := ['one', 'two', 'four', 'five', 'six', 'seven']
|
||||||
for _ in 0 .. 30 {
|
for _ in 0 .. 30 {
|
||||||
e := rand.element(a)?
|
e := rand.element(a)!
|
||||||
assert e in a
|
assert e in a
|
||||||
assert 'three' != e
|
assert 'three' != e
|
||||||
}
|
}
|
||||||
|
@ -423,7 +423,7 @@ fn test_element1() {
|
||||||
|
|
||||||
fn test_element2() {
|
fn test_element2() {
|
||||||
for _ in 0 .. 30 {
|
for _ in 0 .. 30 {
|
||||||
e := rand.element([1, 2, 5, 6, 7, 8])?
|
e := rand.element([1, 2, 5, 6, 7, 8])!
|
||||||
assert e in [1, 2, 5, 6, 7, 8]
|
assert e in [1, 2, 5, 6, 7, 8]
|
||||||
assert 3 != e
|
assert 3 != e
|
||||||
assert 4 != e
|
assert 4 != e
|
||||||
|
|
|
@ -23,7 +23,7 @@ struct Termios {
|
||||||
// an error if the line is empty.
|
// an error if the line is empty.
|
||||||
// The `prompt` `string` is output as a prefix text for the input capturing.
|
// The `prompt` `string` is output as a prefix text for the input capturing.
|
||||||
// read_line_utf8 is the main method of the `readline` module and `Readline` struct.
|
// read_line_utf8 is the main method of the `readline` module and `Readline` struct.
|
||||||
pub fn (mut r Readline) read_line_utf8(prompt string) ?[]rune {
|
pub fn (mut r Readline) read_line_utf8(prompt string) ![]rune {
|
||||||
r.current = []rune{}
|
r.current = []rune{}
|
||||||
r.cursor = 0
|
r.cursor = 0
|
||||||
r.prompt = prompt
|
r.prompt = prompt
|
||||||
|
@ -49,8 +49,8 @@ pub fn (mut r Readline) read_line_utf8(prompt string) ?[]rune {
|
||||||
|
|
||||||
// read_line does the same as `read_line_utf8` but returns user input as a `string`.
|
// read_line does the same as `read_line_utf8` but returns user input as a `string`.
|
||||||
// (As opposed to `[]rune` returned by `read_line_utf8`).
|
// (As opposed to `[]rune` returned by `read_line_utf8`).
|
||||||
pub fn (mut r Readline) read_line(prompt string) ?string {
|
pub fn (mut r Readline) read_line(prompt string) !string {
|
||||||
s := r.read_line_utf8(prompt)?
|
s := r.read_line_utf8(prompt)!
|
||||||
return s.string()
|
return s.string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,9 +63,9 @@ pub fn (mut r Readline) read_line(prompt string) ?string {
|
||||||
// read_line_utf8 is the main method of the `readline` module and `Readline` struct.
|
// read_line_utf8 is the main method of the `readline` module and `Readline` struct.
|
||||||
// NOTE that this version of `read_line_utf8` is a standalone function without
|
// NOTE that this version of `read_line_utf8` is a standalone function without
|
||||||
// persistent functionalities (e.g. history).
|
// persistent functionalities (e.g. history).
|
||||||
pub fn read_line_utf8(prompt string) ?[]rune {
|
pub fn read_line_utf8(prompt string) ![]rune {
|
||||||
mut r := Readline{}
|
mut r := Readline{}
|
||||||
s := r.read_line_utf8(prompt)?
|
s := r.read_line_utf8(prompt)!
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,8 +73,8 @@ pub fn read_line_utf8(prompt string) ?[]rune {
|
||||||
// (As opposed to `[]rune` as returned by `read_line_utf8`).
|
// (As opposed to `[]rune` as returned by `read_line_utf8`).
|
||||||
// NOTE that this version of `read_line` is a standalone function without
|
// NOTE that this version of `read_line` is a standalone function without
|
||||||
// persistent functionalities (e.g. history).
|
// persistent functionalities (e.g. history).
|
||||||
pub fn read_line(prompt string) ?string {
|
pub fn read_line(prompt string) !string {
|
||||||
mut r := Readline{}
|
mut r := Readline{}
|
||||||
s := r.read_line(prompt)?
|
s := r.read_line(prompt)!
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ struct Termios {}
|
||||||
// The `prompt` `string` is output as a prefix text for the input capturing.
|
// The `prompt` `string` is output as a prefix text for the input capturing.
|
||||||
// read_line_utf8 is the main method of the `readline` module and `Readline` struct.
|
// read_line_utf8 is the main method of the `readline` module and `Readline` struct.
|
||||||
|
|
||||||
pub fn (mut r Readline) read_line(prompt string) ?string {
|
pub fn (mut r Readline) read_line(prompt string) !string {
|
||||||
res := ''
|
res := ''
|
||||||
print(prompt)
|
print(prompt)
|
||||||
#const rl = $readline.createInterface({input: $process.stdin,output: $process.stdout,prompt: prompt.str})
|
#const rl = $readline.createInterface({input: $process.stdin,output: $process.stdout,prompt: prompt.str})
|
||||||
|
@ -25,8 +25,8 @@ pub fn (mut r Readline) read_line(prompt string) ?string {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_line(prompt string) ?string {
|
pub fn read_line(prompt string) !string {
|
||||||
mut r := Readline{}
|
mut r := Readline{}
|
||||||
s := r.read_line(prompt)?
|
s := r.read_line(prompt)!
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,7 @@ pub fn (r Readline) read_char() !int {
|
||||||
// an error if the line is empty.
|
// an error if the line is empty.
|
||||||
// The `prompt` `string` is output as a prefix text for the input capturing.
|
// The `prompt` `string` is output as a prefix text for the input capturing.
|
||||||
// read_line_utf8 is the main method of the `readline` module and `Readline` struct.
|
// read_line_utf8 is the main method of the `readline` module and `Readline` struct.
|
||||||
pub fn (mut r Readline) read_line_utf8(prompt string) ?[]rune {
|
pub fn (mut r Readline) read_line_utf8(prompt string) ![]rune {
|
||||||
r.current = []rune{}
|
r.current = []rune{}
|
||||||
r.cursor = 0
|
r.cursor = 0
|
||||||
r.prompt = prompt
|
r.prompt = prompt
|
||||||
|
@ -168,8 +168,8 @@ pub fn (mut r Readline) read_line_utf8(prompt string) ?[]rune {
|
||||||
|
|
||||||
// read_line does the same as `read_line_utf8` but returns user input as a `string`.
|
// read_line does the same as `read_line_utf8` but returns user input as a `string`.
|
||||||
// (As opposed to `[]rune` returned by `read_line_utf8`).
|
// (As opposed to `[]rune` returned by `read_line_utf8`).
|
||||||
pub fn (mut r Readline) read_line(prompt string) ?string {
|
pub fn (mut r Readline) read_line(prompt string) !string {
|
||||||
s := r.read_line_utf8(prompt)?
|
s := r.read_line_utf8(prompt)!
|
||||||
return s.string()
|
return s.string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,9 +182,9 @@ pub fn (mut r Readline) read_line(prompt string) ?string {
|
||||||
// read_line_utf8 is the main method of the `readline` module and `Readline` struct.
|
// read_line_utf8 is the main method of the `readline` module and `Readline` struct.
|
||||||
// NOTE that this version of `read_line_utf8` is a standalone function without
|
// NOTE that this version of `read_line_utf8` is a standalone function without
|
||||||
// persistent functionalities (e.g. history).
|
// persistent functionalities (e.g. history).
|
||||||
pub fn read_line_utf8(prompt string) ?[]rune {
|
pub fn read_line_utf8(prompt string) ![]rune {
|
||||||
mut r := Readline{}
|
mut r := Readline{}
|
||||||
s := r.read_line_utf8(prompt)?
|
s := r.read_line_utf8(prompt)!
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,9 +192,9 @@ pub fn read_line_utf8(prompt string) ?[]rune {
|
||||||
// (As opposed to `[]rune` as returned by `read_line_utf8`).
|
// (As opposed to `[]rune` as returned by `read_line_utf8`).
|
||||||
// NOTE that this version of `read_line` is a standalone function without
|
// NOTE that this version of `read_line` is a standalone function without
|
||||||
// persistent functionalities (e.g. history).
|
// persistent functionalities (e.g. history).
|
||||||
pub fn read_line(prompt string) ?string {
|
pub fn read_line(prompt string) !string {
|
||||||
mut r := Readline{}
|
mut r := Readline{}
|
||||||
s := r.read_line(prompt)?
|
s := r.read_line(prompt)!
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ struct Termios {
|
||||||
// an error if the line is empty.
|
// an error if the line is empty.
|
||||||
// The `prompt` `string` is output as a prefix text for the input capturing.
|
// The `prompt` `string` is output as a prefix text for the input capturing.
|
||||||
// read_line_utf8 is the main method of the `readline` module and `Readline` struct.
|
// read_line_utf8 is the main method of the `readline` module and `Readline` struct.
|
||||||
pub fn (mut r Readline) read_line_utf8(prompt string) ?[]rune {
|
pub fn (mut r Readline) read_line_utf8(prompt string) ![]rune {
|
||||||
r.current = []rune{}
|
r.current = []rune{}
|
||||||
r.cursor = 0
|
r.cursor = 0
|
||||||
r.prompt = prompt
|
r.prompt = prompt
|
||||||
|
@ -47,8 +47,8 @@ pub fn (mut r Readline) read_line_utf8(prompt string) ?[]rune {
|
||||||
|
|
||||||
// read_line does the same as `read_line_utf8` but returns user input as a `string`.
|
// read_line does the same as `read_line_utf8` but returns user input as a `string`.
|
||||||
// (As opposed to `[]rune` returned by `read_line_utf8`).
|
// (As opposed to `[]rune` returned by `read_line_utf8`).
|
||||||
pub fn (mut r Readline) read_line(prompt string) ?string {
|
pub fn (mut r Readline) read_line(prompt string) !string {
|
||||||
s := r.read_line_utf8(prompt)?
|
s := r.read_line_utf8(prompt)!
|
||||||
return s.string()
|
return s.string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,9 +61,9 @@ pub fn (mut r Readline) read_line(prompt string) ?string {
|
||||||
// read_line_utf8 is the main method of the `readline` module and `Readline` struct.
|
// read_line_utf8 is the main method of the `readline` module and `Readline` struct.
|
||||||
// NOTE that this version of `read_line_utf8` is a standalone function without
|
// NOTE that this version of `read_line_utf8` is a standalone function without
|
||||||
// persistent functionalities (e.g. history).
|
// persistent functionalities (e.g. history).
|
||||||
pub fn read_line_utf8(prompt string) ?[]rune {
|
pub fn read_line_utf8(prompt string) ![]rune {
|
||||||
mut r := Readline{}
|
mut r := Readline{}
|
||||||
s := r.read_line_utf8(prompt)?
|
s := r.read_line_utf8(prompt)!
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,8 +71,8 @@ pub fn read_line_utf8(prompt string) ?[]rune {
|
||||||
// (As opposed to `[]rune` as returned by `read_line_utf8`).
|
// (As opposed to `[]rune` as returned by `read_line_utf8`).
|
||||||
// NOTE that this version of `read_line` is a standalone function without
|
// NOTE that this version of `read_line` is a standalone function without
|
||||||
// persistent functionalities (e.g. history).
|
// persistent functionalities (e.g. history).
|
||||||
pub fn read_line(prompt string) ?string {
|
pub fn read_line(prompt string) !string {
|
||||||
mut r := Readline{}
|
mut r := Readline{}
|
||||||
s := r.read_line(prompt)?
|
s := r.read_line(prompt)!
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
module embed_file
|
module embed_file
|
||||||
|
|
||||||
interface Decoder {
|
interface Decoder {
|
||||||
decompress([]u8) ?[]u8
|
decompress([]u8) ![]u8
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EmbedFileDecoders {
|
struct EmbedFileDecoders {
|
||||||
|
|
|
@ -22,7 +22,7 @@ fn test_out_files() {
|
||||||
println(term.colorize(term.green, '> testing whether .out files match:'))
|
println(term.colorize(term.green, '> testing whether .out files match:'))
|
||||||
os.chdir(vroot) or {}
|
os.chdir(vroot) or {}
|
||||||
output_path := os.join_path(os.temp_dir(), 'v', 'coutput', 'out')
|
output_path := os.join_path(os.temp_dir(), 'v', 'coutput', 'out')
|
||||||
os.mkdir_all(output_path)?
|
os.mkdir_all(output_path)!
|
||||||
defer {
|
defer {
|
||||||
os.rmdir_all(output_path) or {}
|
os.rmdir_all(output_path) or {}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ fn test_out_files() {
|
||||||
panic(res.output)
|
panic(res.output)
|
||||||
}
|
}
|
||||||
mut found := res.output.trim_right('\r\n').replace('\r\n', '\n')
|
mut found := res.output.trim_right('\r\n').replace('\r\n', '\n')
|
||||||
mut expected := os.read_file(out_path)?
|
mut expected := os.read_file(out_path)!
|
||||||
expected = expected.trim_right('\r\n').replace('\r\n', '\n')
|
expected = expected.trim_right('\r\n').replace('\r\n', '\n')
|
||||||
if expected.contains('================ V panic ================') {
|
if expected.contains('================ V panic ================') {
|
||||||
// panic include backtraces and absolute file paths, so can't do char by char comparison
|
// panic include backtraces and absolute file paths, so can't do char by char comparison
|
||||||
|
@ -93,7 +93,7 @@ fn test_c_must_have_files() {
|
||||||
println(term.colorize(term.green, '> testing whether `.c.must_have` files match:'))
|
println(term.colorize(term.green, '> testing whether `.c.must_have` files match:'))
|
||||||
os.chdir(vroot) or {}
|
os.chdir(vroot) or {}
|
||||||
output_path := os.join_path(os.temp_dir(), 'v', 'coutput', 'c_must_have')
|
output_path := os.join_path(os.temp_dir(), 'v', 'coutput', 'c_must_have')
|
||||||
os.mkdir_all(output_path)?
|
os.mkdir_all(output_path)!
|
||||||
defer {
|
defer {
|
||||||
os.rmdir_all(output_path) or {}
|
os.rmdir_all(output_path) or {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
{1, { .str=(byteptr)("embed.vv"), .len=8, .is_lit=1 }, { .str=(byteptr)("none"), .len=4, .is_lit=1 }, _v_embed_blob_1},
|
{1, { .str=(byteptr)("embed.vv"), .len=8, .is_lit=1 }, { .str=(byteptr)("none"), .len=4, .is_lit=1 }, _v_embed_blob_1},
|
||||||
|
|
||||||
VV_LOCAL_SYMBOL void v__preludes__embed_file__zlib__init(void);
|
VV_LOCAL_SYMBOL void v__preludes__embed_file__zlib__init(void);
|
||||||
VV_LOCAL_SYMBOL _option_Array_u8 v__preludes__embed_file__zlib__ZLibDecoder_decompress(v__preludes__embed_file__zlib__ZLibDecoder _d1, Array_u8 data) {
|
VV_LOCAL_SYMBOL _result_Array_u8 v__preludes__embed_file__zlib__ZLibDecoder_decompress(v__preludes__embed_file__zlib__ZLibDecoder _d1, Array_u8 data) {
|
||||||
= compress__zlib__decompress(data);
|
= compress__zlib__decompress(data);
|
||||||
|
|
||||||
res.compressed = v__embed_file__find_index_entry_by_path((voidptr)_v_embed_file_index, _SLIT("embed.vv"), _SLIT("zlib"))->data;
|
res.compressed = v__embed_file__find_index_entry_by_path((voidptr)_v_embed_file_index, _SLIT("embed.vv"), _SLIT("zlib"))->data;
|
||||||
|
|
|
@ -5,7 +5,7 @@ import v.embed_file
|
||||||
|
|
||||||
struct ZLibDecoder {}
|
struct ZLibDecoder {}
|
||||||
|
|
||||||
fn (_ ZLibDecoder) decompress(data []u8) ?[]u8 {
|
fn (_ ZLibDecoder) decompress(data []u8) ![]u8 {
|
||||||
return zlib.decompress(data)
|
return zlib.decompress(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import compress.zlib as z
|
import compress.zlib as z
|
||||||
z.compress('hello world'.bytes())?
|
z.compress('hello world'.bytes())!
|
||||||
===output===
|
===output===
|
||||||
[120, 1, 1, 11, 0, 244, 255, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 26, 11, 4, 93]
|
[120, 1, 1, 11, 0, 244, 255, 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 26, 11, 4, 93]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue