docs,ci: check more vlib modules in the report-missing-dots-in-doc-comments job (#24928)

This commit is contained in:
Delyan Angelov 2025-07-19 11:51:01 +03:00 committed by GitHub
parent ae9a69bdf7
commit 3725576729
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
69 changed files with 272 additions and 387 deletions

View file

@ -65,4 +65,8 @@ jobs:
- name: Build V - name: Build V
run: make run: make
- name: Check doc comment dots for some key modules - name: Check doc comment dots for some key modules
run: ./v run cmd/tools/find_doc_comments_with_no_dots.v vlib/builtin/ vlib/arrays/ vlib/flag/ vlib/bitfield/ run: ./v run cmd/tools/find_doc_comments_with_no_dots.v \
vlib/builtin/ vlib/arrays/ vlib/flag/ \
vlib/bitfield/ vlib/term/ vlib/strings/ \
vlib/rand/ vlib/compress/ vlib/clipboard/ \
vlib/os

View file

@ -41,15 +41,13 @@ pub fn (mut cb Clipboard) clear() {
//#[cb->pb clearContents]; //#[cb->pb clearContents];
} }
// free releases all memory associated with the clipboard // free releases all memory associated with the clipboard instance.
// instance.
pub fn (mut cb Clipboard) free() { pub fn (mut cb Clipboard) free() {
cb.foo = 0 cb.foo = 0
// nothing to free // nothing to free
} }
// has_ownership returns true if the contents of // has_ownership returns true if the contents of the clipboard were created by this clipboard instance.
// the clipboard were created by this clipboard instance.
pub fn (cb &Clipboard) has_ownership() bool { pub fn (cb &Clipboard) has_ownership() bool {
if cb.last_cb_serial == 0 { if cb.last_cb_serial == 0 {
return false return false
@ -66,8 +64,7 @@ pub fn (mut cb Clipboard) set_text(text string) bool {
return C.darwin_set_pasteboard_text(cb.pb, text) return C.darwin_set_pasteboard_text(cb.pb, text)
} }
// get_text retrieves the contents of the system clipboard // get_text retrieves the contents of the system clipboard.
// as a `string`.
// This is often associated with a *paste* action (`Cmd` + `V`). // This is often associated with a *paste* action (`Cmd` + `V`).
pub fn (mut cb Clipboard) get_text() string { pub fn (mut cb Clipboard) get_text() string {
cb.foo = 0 cb.foo = 0

View file

@ -115,8 +115,7 @@ pub fn (cb &Clipboard) check_availability() bool {
return cb.hwnd != unsafe { nil } return cb.hwnd != unsafe { nil }
} }
// has_ownership returns true if the contents of // has_ownership returns true if the contents of the clipboard were created by this clipboard instance.
// the clipboard were created by this clipboard instance.
pub fn (cb &Clipboard) has_ownership() bool { pub fn (cb &Clipboard) has_ownership() bool {
return voidptr(C.GetClipboardOwner()) == cb.hwnd return voidptr(C.GetClipboardOwner()) == cb.hwnd
} }
@ -131,8 +130,7 @@ pub fn (mut cb Clipboard) clear() {
cb.foo = 0 cb.foo = 0
} }
// free releases all memory associated with the clipboard // free releases all memory associated with the clipboard instance.
// instance.
pub fn (mut cb Clipboard) free() { pub fn (mut cb Clipboard) free() {
C.DestroyWindow(cb.hwnd) C.DestroyWindow(cb.hwnd)
cb.foo = 0 cb.foo = 0
@ -180,8 +178,7 @@ pub fn (mut cb Clipboard) set_text(text string) bool {
return true return true
} }
// get_text retrieves the contents of the system clipboard // get_text retrieves the contents of the system clipboard.
// as a `string`.
// This is often associated with a *paste* action (`Ctrl` + `V`). // This is often associated with a *paste* action (`Ctrl` + `V`).
pub fn (mut cb Clipboard) get_text() string { pub fn (mut cb Clipboard) get_text() string {
cb.foo = 0 cb.foo = 0

View file

@ -32,8 +32,7 @@ pub fn (mut cb Clipboard) set_text(text string) bool {
return true return true
} }
// get_text retrieves the contents of the system clipboard // get_text retrieves the contents of the system clipboard.
// as a `string`.
// This is often associated with a *paste* action (`Ctrl` + `V`). // This is often associated with a *paste* action (`Ctrl` + `V`).
pub fn (mut cb Clipboard) get_text() string { pub fn (mut cb Clipboard) get_text() string {
return cb.text return cb.text
@ -45,13 +44,11 @@ pub fn (mut cb Clipboard) clear() {
cb.is_owner = false cb.is_owner = false
} }
// free releases all memory associated with the clipboard // free releases all memory associated with the clipboard instance.
// instance.
pub fn (mut cb Clipboard) free() { pub fn (mut cb Clipboard) free() {
} }
// has_ownership returns true if the contents of // has_ownership returns true if the contents of the clipboard were created by this clipboard instance.
// the clipboard were created by this clipboard instance.
pub fn (cb &Clipboard) has_ownership() bool { pub fn (cb &Clipboard) has_ownership() bool {
return cb.is_owner return cb.is_owner
} }

View file

@ -59,8 +59,7 @@ pub fn decompress(data []u8, flags int) ![]u8 {
// to pass arbitrary data, without having to create a closure. // to pass arbitrary data, without having to create a closure.
pub type ChunkCallback = fn (chunk []u8, userdata voidptr) int pub type ChunkCallback = fn (chunk []u8, userdata voidptr) int
// decompress_with_callback decompresses an array of bytes based on the provided flags, // decompress_with_callback decompresses an array of bytes, based on the provided flags, and a V fn callback to receive decompressed chunks, of at most 32 kilobytes each.
// and a V fn callback to receive decompressed chunks, of at most 32 kilobytes each.
// It returns the total decompressed length, or a decompression error. // It returns the total decompressed length, or a decompression error.
// 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.
pub fn decompress_with_callback(data []u8, cb ChunkCallback, userdata voidptr, flags int) !u64 { pub fn decompress_with_callback(data []u8, cb ChunkCallback, userdata voidptr, flags int) !u64 {

View file

@ -203,7 +203,7 @@ pub fn validate(data []u8, params DecompressParams) !GzipHeader {
return header return header
} }
// decompress an array of bytes using zlib and returns the decompressed bytes in a new array // decompress 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 {
gzip_header := validate(data, params)! gzip_header := validate(data, params)!

View file

@ -65,7 +65,7 @@ pub enum CompressionLevel {
default_compression = C.MZ_DEFAULT_COMPRESSION default_compression = C.MZ_DEFAULT_COMPRESSION
} }
// OpenMode lists the opening modes // OpenMode lists the opening modes.
// .write: opens a file for reading/extracting (the file must exists). // .write: opens a file for reading/extracting (the file must exists).
// .read_only: creates an empty file for writing. // .read_only: creates an empty file for writing.
// .append: appends to an existing archive. // .append: appends to an existing archive.
@ -214,7 +214,7 @@ pub fn (mut zentry Zip) read_entry() !voidptr {
return buf return buf
} }
// read_entry_buf extracts the current zip entry into user specified buffer // read_entry_buf extracts the current zip entry into user specified buffer.
pub fn (mut zentry Zip) read_entry_buf(buf voidptr, in_bsize int) !int { pub fn (mut zentry Zip) read_entry_buf(buf voidptr, in_bsize int) !int {
bsize := usize(in_bsize) bsize := usize(in_bsize)
res := C.zip_entry_noallocread(zentry, buf, bsize) res := C.zip_entry_noallocread(zentry, buf, bsize)
@ -232,7 +232,7 @@ pub fn (mut zentry Zip) extract_entry(path string) ! {
} }
} }
// extract zip file to directory // extract zip file to directory.
pub fn extract_zip_to_dir(file string, dir string) !bool { pub fn extract_zip_to_dir(file string, dir string) !bool {
if C.access(&char(dir.str), 0) == -1 { if C.access(&char(dir.str), 0) == -1 {
return error('szip: cannot open directory for extracting, directory not exists') return error('szip: cannot open directory for extracting, directory not exists')
@ -241,7 +241,7 @@ pub fn extract_zip_to_dir(file string, dir string) !bool {
return res == 0 return res == 0
} }
// zip files (full path) to zip file // zip files (full path) to zip file.
pub fn zip_files(path_to_file []string, path_to_export_zip string) ! { pub fn zip_files(path_to_file []string, path_to_export_zip string) ! {
// open or create new zip // open or create new zip
mut zip := open(path_to_export_zip, .no_compression, .write) or { panic(err) } mut zip := open(path_to_export_zip, .no_compression, .write) or { panic(err) }

View file

@ -458,7 +458,7 @@ mut:
ctx &C.ZSTD_CCtx ctx &C.ZSTD_CCtx
} }
// new_cctx create a compression context // new_cctx create a compression context.
// extra compression parameters can be set by `params` // extra compression parameters can be set by `params`
pub fn new_cctx(params CompressParams) !&CCtx { pub fn new_cctx(params CompressParams) !&CCtx {
mut ctx := C.ZSTD_createCCtx() mut ctx := C.ZSTD_createCCtx()
@ -492,7 +492,7 @@ pub fn (mut c CCtx) compress_stream2(output &OutBuffer, input &InBuffer, mode En
return res return res
} }
// free_cctx free a compression context // free_cctx free a compression context.
pub fn (mut c CCtx) free_cctx() usize { pub fn (mut c CCtx) free_cctx() usize {
return C.ZSTD_freeCCtx(c.ctx) return C.ZSTD_freeCCtx(c.ctx)
} }
@ -506,7 +506,7 @@ mut:
ctx &C.ZSTD_DCtx ctx &C.ZSTD_DCtx
} }
// new_dctx creates a decompression context // new_dctx creates a decompression context.
// extra decompression parameters can be set by `params` // extra decompression parameters can be set by `params`
pub fn new_dctx(params DecompressParams) !&DCtx { pub fn new_dctx(params DecompressParams) !&DCtx {
mut ctx := C.ZSTD_createDCtx() mut ctx := C.ZSTD_createDCtx()

View file

@ -5,7 +5,7 @@ module os
fn C.ptrace(int, u32, voidptr, int) int fn C.ptrace(int, u32, voidptr, int) int
// debugger_present returns a bool indicating if the process is being debugged // debugger_present returns a bool indicating if the process is being debugged.
pub fn debugger_present() bool { pub fn debugger_present() bool {
$if macos { $if macos {
// check if a child process could trace its parent process, // check if a child process could trace its parent process,

View file

@ -4,7 +4,7 @@ module os
fn C.ptrace(int, u32, voidptr, int) int fn C.ptrace(int, u32, voidptr, int) int
// debugger_present returns a bool indicating if the process is being debugged // debugger_present returns a bool indicating if the process is being debugged.
pub fn debugger_present() bool { pub fn debugger_present() bool {
$if freebsd { $if freebsd {
// check if a child process could trace its parent process, // check if a child process could trace its parent process,

View file

@ -4,7 +4,7 @@ module os
fn C.ptrace(u32, u32, voidptr, voidptr) u64 fn C.ptrace(u32, u32, voidptr, voidptr) u64
// debugger_present returns a bool indicating if the process is being debugged // debugger_present returns a bool indicating if the process is being debugged.
pub fn debugger_present() bool { pub fn debugger_present() bool {
$if cross ? { $if cross ? {
return false return false

View file

@ -4,7 +4,7 @@ module os
fn C.ptrace(int, u32, voidptr, int) int fn C.ptrace(int, u32, voidptr, int) int
// debugger_present returns a bool indicating if the process is being debugged // debugger_present returns a bool indicating if the process is being debugged.
pub fn debugger_present() bool { pub fn debugger_present() bool {
$if openbsd { $if openbsd {
// check if a child process could trace its parent process, // check if a child process could trace its parent process,

View file

@ -641,8 +641,7 @@ pub fn (mut f File) read_raw[T]() !T {
return t return t
} }
// read_raw_at reads and returns a single instance of type `T` starting at file // read_raw_at reads and returns a single instance of type `T` starting at file byte offset `pos`.
// byte offset `pos`.
pub fn (mut f File) read_raw_at[T](pos u64) !T { pub fn (mut f File) read_raw_at[T](pos u64) !T {
if !f.is_opened { if !f.is_opened {
return error_file_not_opened() return error_file_not_opened()
@ -823,9 +822,8 @@ pub enum SeekMode {
end end
} }
// seek moves the file cursor (if any) associated with a file // seek moves the file cursor (if any) associated with a file to a new location, offset `pos` bytes from the origin.
// to a new location, offset `pos` bytes from the origin. The origin // The origin is dependent on the `mode` and can be:
// is dependent on the `mode` and can be:
// .start -> the origin is the start of the file // .start -> the origin is the start of the file
// .current -> the current position/cursor in the file // .current -> the current position/cursor in the file
// .end -> the end of the file // .end -> the end of the file
@ -854,9 +852,8 @@ pub fn (mut f File) seek(pos i64, mode SeekMode) ! {
} }
} }
// tell will return the current offset of the file cursor measured from // tell will return the current offset of the file cursor measured from the start of the file, in bytes.
// the start of the file, in bytes. It is complementary to seek, i.e. // It is complementary to seek, i.e. you can use the return value as the `pos` parameter to .seek( pos, .start ),
// you can use the return value as the `pos` parameter to .seek( pos, .start ),
// so that your next read will happen from the same place. // so that your next read will happen from the same place.
pub fn (f &File) tell() !i64 { pub fn (f &File) tell() !i64 {
if !f.is_opened { if !f.is_opened {

View file

@ -126,7 +126,7 @@ pub fn (mut f File) write_to(pos u64, buf []u8) !int {
return nbytes return nbytes
} }
// write_string writes the string `s` into the file // write_string writes the string `s` into the file.
// It returns how many bytes were actually written. // It returns how many bytes were actually written.
pub fn (mut f File) write_string(s string) !int { pub fn (mut f File) write_string(s string) !int {
nbytes := f.write(s.bytes())! nbytes := f.write(s.bytes())!

View file

@ -27,9 +27,7 @@ pub fn is_abs_path(path string) bool {
return path[0] == fslash return path[0] == fslash
} }
// abs_path joins the current working directory // abs_path joins the current working directory with the given `path` (if the `path` is relative), and returns the absolute path representation.
// with the given `path` (if the `path` is relative)
// and returns the absolute path representation.
pub fn abs_path(path string) string { pub fn abs_path(path string) string {
wd := getwd() wd := getwd()
if path == '' { if path == '' {
@ -218,8 +216,7 @@ fn clean_path(path string) string {
return res return res
} }
// to_slash returns the result of replacing each separator character // to_slash returns the result of replacing each separator character in path with a slash (`/`).
// in path with a slash (`/`).
pub fn to_slash(path string) string { pub fn to_slash(path string) string {
if path_separator == '/' { if path_separator == '/' {
return path return path
@ -227,8 +224,7 @@ pub fn to_slash(path string) string {
return path.replace(path_separator, '/') return path.replace(path_separator, '/')
} }
// from_slash returns the result of replacing each slash (`/`) character // from_slash returns the result of replacing each slash (`/`) character is path with a separator character.
// is path with a separator character.
pub fn from_slash(path string) string { pub fn from_slash(path string) string {
if path_separator == '/' { if path_separator == '/' {
return path return path

View file

@ -36,8 +36,7 @@ pub:
execute bool execute bool
} }
// bitmask returns a 3 bit sequence in the order RWE where // bitmask returns a 3 bit sequence in the order RWE, where the bit is set to 1 if the value is true or 0 otherwise.
// the bit is set to 1 if the value is true or 0 otherwise.
pub fn (p FilePermission) bitmask() u32 { pub fn (p FilePermission) bitmask() u32 {
mut mask := u32(0) mut mask := u32(0)
if p.read { if p.read {

View file

@ -33,7 +33,7 @@ pub:
kind FdEventType kind FdEventType
} }
// new creates a new KqueueNotifier // new creates a new KqueueNotifier.
// The FdNotifier interface is returned to allow OS specific // The FdNotifier interface is returned to allow OS specific
// implementations without exposing the concrete type // implementations without exposing the concrete type
pub fn new() !FdNotifier { pub fn new() !FdNotifier {

View file

@ -38,7 +38,7 @@ pub:
kind FdEventType kind FdEventType
} }
// new creates a new EpollNotifier // new creates a new EpollNotifier.
// The FdNotifier interface is returned to allow OS specific // The FdNotifier interface is returned to allow OS specific
// implementations without exposing the concrete type // implementations without exposing the concrete type
pub fn new() !FdNotifier { pub fn new() !FdNotifier {

View file

@ -1047,8 +1047,7 @@ pub fn execve(cmdpath string, cmdargs []string, envs []string) ! {
} }
} }
// is_atty returns 1 if the `fd` file descriptor is open and refers to a // is_atty returns 1 if the `fd` file descriptor is open and refers to a terminal.
// terminal.
pub fn is_atty(fd int) int { pub fn is_atty(fd int) int {
$if windows { $if windows {
mut mode := u32(0) mut mode := u32(0)

View file

@ -71,8 +71,7 @@ fn executable_fallback() string {
return exepath return exepath
} }
// cp_all will recursively copy `src` to `dst`, // cp_all will recursively copy `src` to `dst`, optionally overwriting files or dirs in `dst`.
// optionally overwriting files or dirs in `dst`.
pub fn cp_all(src string, dst string, overwrite bool) ! { pub fn cp_all(src string, dst string, overwrite bool) ! {
source_path := real_path(src) source_path := real_path(src)
dest_path := real_path(dst) dest_path := real_path(dst)
@ -588,8 +587,7 @@ fn error_failed_to_find_executable() IError {
return &ExecutableNotFoundError{} return &ExecutableNotFoundError{}
} }
// find_abs_path_of_executable searches the environment PATH for the // find_abs_path_of_executable searches the environment PATH for the absolute path of the given executable name.
// absolute path of the given executable name.
pub fn find_abs_path_of_executable(exe_name string) !string { pub fn find_abs_path_of_executable(exe_name string) !string {
if exe_name == '' { if exe_name == '' {
return error('expected non empty `exe_name`') return error('expected non empty `exe_name`')
@ -792,7 +790,7 @@ pub fn walk(path string, f fn (string)) {
} }
} }
// FnWalkContextCB is used to define the callback functions, passed to os.walk_context // FnWalkContextCB is used to define the callback functions, passed to os.walk_context.
pub type FnWalkContextCB = fn (voidptr, string) pub type FnWalkContextCB = fn (voidptr, string)
// walk_with_context traverses the given directory `path`. // walk_with_context traverses the given directory `path`.
@ -927,9 +925,9 @@ pub fn data_dir() string {
return xdg_home_folder('XDG_DATA_HOME', '.local/share') return xdg_home_folder('XDG_DATA_HOME', '.local/share')
} }
// state_dir returns a *writable* folder user-specific folder, suitable for storing state data, // state_dir returns a *writable* folder user-specific folder.
// that should persist between (application) restarts, but that is not important or portable // It is suitable for storing state data, that should persist between (application) restarts,
// enough to the user that it should be stored in os.data_dir(). // but that is not important or portable enough to the user that it should be stored in os.data_dir().
// See: https://specifications.freedesktop.org/basedir-spec/latest/ . // See: https://specifications.freedesktop.org/basedir-spec/latest/ .
// `$XDG_STATE_HOME` defines the base directory relative to which user-specific state files should be stored. // `$XDG_STATE_HOME` defines the base directory relative to which user-specific state files should be stored.
// If `$XDG_STATE_HOME` is either not set or empty, a default equal to // If `$XDG_STATE_HOME` is either not set or empty, a default equal to
@ -941,8 +939,8 @@ pub fn state_dir() string {
return xdg_home_folder('XDG_STATE_HOME', '.local/state') return xdg_home_folder('XDG_STATE_HOME', '.local/state')
} }
// local_bin_dir returns `$HOME/.local/bin`, which is *guaranteed* to be in the PATH of the current user, for // local_bin_dir returns `$HOME/.local/bin`, which is *guaranteed* to be in the PATH of the current user.
// distributions, following the XDG spec from https://specifications.freedesktop.org/basedir-spec/latest/ : // It is compatible with stributions, following the XDG spec from https://specifications.freedesktop.org/basedir-spec/latest/ :
// > User-specific executable files may be stored in `$HOME/.local/bin`. // > User-specific executable files may be stored in `$HOME/.local/bin`.
// > Distributions should ensure this directory shows up in the UNIX $PATH environment variable, at an appropriate place. // > Distributions should ensure this directory shows up in the UNIX $PATH environment variable, at an appropriate place.
pub fn local_bin_dir() string { pub fn local_bin_dir() string {
@ -986,8 +984,8 @@ pub fn temp_dir() string {
return path return path
} }
// vtmp_dir returns the path to a folder, that is writable to V programs, *and* specific // vtmp_dir returns the path to a folder, that is writable to V programs, *and* specific to the OS user.
// to the OS user. It can be overridden by setting the env variable `VTMP`. // It can be overridden by setting the env variable `VTMP`.
pub fn vtmp_dir() string { pub fn vtmp_dir() string {
mut vtmp := getenv('VTMP') mut vtmp := getenv('VTMP')
if vtmp.len > 0 { if vtmp.len > 0 {
@ -1078,8 +1076,7 @@ pub mut:
machine string machine string
} }
// execute_or_panic returns the os.Result of executing `cmd`, or panic with its // execute_or_panic returns the os.Result of executing `cmd`, or panic with its output on failure.
// output on failure.
pub fn execute_or_panic(cmd string) Result { pub fn execute_or_panic(cmd string) Result {
res := execute(cmd) res := execute(cmd)
if res.exit_code != 0 { if res.exit_code != 0 {
@ -1090,8 +1087,7 @@ pub fn execute_or_panic(cmd string) Result {
return res return res
} }
// execute_or_exit returns the os.Result of executing `cmd`, or exit with its // execute_or_exit returns the os.Result of executing `cmd`, or exit with its output on failure.
// output on failure.
pub fn execute_or_exit(cmd string) Result { pub fn execute_or_exit(cmd string) Result {
res := execute(cmd) res := execute(cmd)
if res.exit_code != 0 { if res.exit_code != 0 {
@ -1155,7 +1151,7 @@ pub fn config_dir() !string {
return error('Cannot find config directory') return error('Cannot find config directory')
} }
// Stat struct modeled on POSIX // Stat struct modeled on POSIX.
pub struct Stat { pub struct Stat {
pub: pub:
dev u64 // ID of device containing file dev u64 // ID of device containing file

View file

@ -36,7 +36,7 @@ pub type AssetManager = C.AAssetManager
fn C.AAssetManager_open(&C.AAssetManager, &char, int) &C.AAsset fn C.AAssetManager_open(&C.AAssetManager, &char, int) &C.AAsset
// open opens an Android `Asset` // open opens an Android `Asset`.
pub fn (am &AssetManager) open(filename string, mode AssetMode) !&Asset { pub fn (am &AssetManager) open(filename string, mode AssetMode) !&Asset {
asset := C.AAssetManager_open(am, filename.str, int(mode)) asset := C.AAssetManager_open(am, filename.str, int(mode))
if isnil(asset) { if isnil(asset) {
@ -66,8 +66,7 @@ pub fn (a &Asset) get_length() int {
fn C.AAsset_getLength64(&C.AAsset) i64 fn C.AAsset_getLength64(&C.AAsset) i64
// get_length_64 returns the total size of the asset data using // get_length_64 returns the total size of the asset data using a 64-bit number instead of 32-bit as `get_length`.
// a 64-bit number instead of 32-bit as `get_length`.
pub fn (a &Asset) get_length_64() i64 { pub fn (a &Asset) get_length_64() i64 {
return C.AAsset_getLength64(a) return C.AAsset_getLength64(a)
} }

View file

@ -10,12 +10,10 @@ import strings
#include <sys/statvfs.h> #include <sys/statvfs.h>
#include <utime.h> #include <utime.h>
// path_separator is the platform specific separator string, used between the folders // path_separator is the platform specific separator string, used between the folders and filenames in a path. It is '/' on POSIX, and '\\' on Windows.
// and filenames in a path. It is '/' on POSIX, and '\\' on Windows.
pub const path_separator = '/' pub const path_separator = '/'
// path_delimiter is the platform specific delimiter string, used between the paths // path_delimiter is the platform specific delimiter string, used between the paths in environment variables like PATH. It is ':' on POSIX, and ';' on Windows.
// in environment variables like PATH. It is ':' on POSIX, and ';' on Windows.
pub const path_delimiter = ':' pub const path_delimiter = ':'
// path_devnull is a platform-specific file path of the null device. // path_devnull is a platform-specific file path of the null device.
@ -214,9 +212,8 @@ fn native_glob_pattern(pattern string, mut matches []string) ! {
} }
} }
// utime changes the access and modification times of the inode specified by // utime changes the access and modification times of the inode specified by path.
// path to the actime and modtime fields of times respectively, or returns POSIX // It returns POSIX error message, if it can not do so.
// error message if utime call fails.
pub fn utime(path string, actime int, modtime int) ! { pub fn utime(path string, actime int, modtime int) ! {
u := C.utimbuf{actime, modtime} u := C.utimbuf{actime, modtime}
if C.utime(&char(path.str), &u) != 0 { if C.utime(&char(path.str), &u) != 0 {
@ -224,7 +221,7 @@ pub fn utime(path string, actime int, modtime int) ! {
} }
} }
// uname returns information about the platform on which the program is running // uname returns information about the platform on which the program is running.
// For example: // For example:
// os.Uname{ // os.Uname{
// sysname: 'Linux' // sysname: 'Linux'
@ -256,8 +253,7 @@ pub fn uname() Uname {
return u return u
} }
// hostname returns the hostname (system's DNS name) or POSIX error message if // hostname returns the hostname (system's DNS name) or POSIX error message if the hostname call fails.
// the hostname call fails.
pub fn hostname() !string { pub fn hostname() !string {
mut hstnme := '' mut hstnme := ''
size := 256 size := 256
@ -270,8 +266,8 @@ pub fn hostname() !string {
return error(posix_get_error_msg(C.errno)) return error(posix_get_error_msg(C.errno))
} }
// loginname returns the name of the user logged in on the controlling terminal // loginname returns the name of the user logged in on the controlling terminal of the process.
// of the process or POSIX error message if the getlogin call fails. // It returns a POSIX error message, if the getlogin call fails.
pub fn loginname() !string { pub fn loginname() !string {
x := C.getlogin() x := C.getlogin()
if !isnil(x) { if !isnil(x) {
@ -427,8 +423,8 @@ pub fn (mut c Command) close() ! {
} }
} }
// symlink creates a symbolic link named target, which points to origin // symlink creates a symbolic link named target, which points to origin.
// or returns POSIX error message if symlink call fails. // It returns a POSIX error message, if it can not do so.
pub fn symlink(origin string, target string) ! { pub fn symlink(origin string, target string) ! {
res := C.symlink(&char(origin.str), &char(target.str)) res := C.symlink(&char(origin.str), &char(target.str))
if res == 0 { if res == 0 {
@ -437,8 +433,8 @@ pub fn symlink(origin string, target string) ! {
return error(posix_get_error_msg(C.errno)) return error(posix_get_error_msg(C.errno))
} }
// link creates a new link (also known as a hard link) to an existing file or // link creates a new link (also known as a hard link) to an existing file.
// returns POSIX error message if link call fails. // It returns a POSIX error message, if it can not do so.
pub fn link(origin string, target string) ! { pub fn link(origin string, target string) ! {
res := C.link(&char(origin.str), &char(target.str)) res := C.link(&char(origin.str), &char(target.str))
if res == 0 { if res == 0 {

View file

@ -1,9 +1,9 @@
module os module os
// stat returns a platform-agnostic Stat struct comparable to what is // stat returns a platform-agnostic Stat struct, containing metadata about the given file/folder path.
// available in other programming languages and fails with the POSIX // It returns a POSIX error, if it can not do so.
// error if the stat call fails. Symlinks are followed and the resulting // Note: symlinks are followed, and the resulting Stat for their target will be returned.
// Stat provided. (If this is not desired, use lstat().) // If this is not desired, call lstat/1 instead.
pub fn stat(path string) !Stat { pub fn stat(path string) !Stat {
mut s := C.stat{} mut s := C.stat{}
unsafe { unsafe {
@ -27,10 +27,8 @@ pub fn stat(path string) !Stat {
} }
} }
// lstat returns a platform-agnostic Stat struct comparable to what is // lstat is similar to stat/1 for normal files/folders.
// available in other programming languages and fails with the POSIX // Unlike stat/1, however, it will return the stat info for a symlink, instead of its target.
// error if the stat call fails. If a link is stat'd, the stat info
// for the link is provided.
pub fn lstat(path string) !Stat { pub fn lstat(path string) !Stat {
mut s := C.stat{} mut s := C.stat{}
unsafe { unsafe {
@ -54,7 +52,7 @@ pub fn lstat(path string) !Stat {
} }
} }
// get_filetype returns the FileType from the Stat struct // get_filetype returns the FileType from the Stat struct.
pub fn (st Stat) get_filetype() FileType { pub fn (st Stat) get_filetype() FileType {
match st.mode & u32(C.S_IFMT) { match st.mode & u32(C.S_IFMT) {
u32(C.S_IFREG) { u32(C.S_IFREG) {
@ -84,8 +82,7 @@ pub fn (st Stat) get_filetype() FileType {
} }
} }
// get_mode returns the file type and permissions (readable, writable, executable) // get_mode returns the file type and permissions (readable, writable, executable) in owner/group/others format.
// in owner/group/others format.
pub fn (st Stat) get_mode() FileMode { pub fn (st Stat) get_mode() FileMode {
return FileMode{ return FileMode{
typ: st.get_filetype() typ: st.get_filetype()

View file

@ -1,9 +1,7 @@
module os module os
// stat returns a platform-agnostic Stat struct comparable to what is // stat returns metadata for the given file/folder.
// available in other programming languages and fails with the POSIX // It will return a POSIX error message, if it can not do so.
// error if the stat call fails. In Windows, there is no lstat so
// information on a link cannot be provided.
// C._wstat64() can be used on 32- and 64-bit Windows per // C._wstat64() can be used on 32- and 64-bit Windows per
// https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/stat-functions?view=msvc-170 // https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/stat-functions?view=msvc-170
pub fn stat(path string) !Stat { pub fn stat(path string) !Stat {
@ -29,13 +27,13 @@ pub fn stat(path string) !Stat {
} }
} }
// lstat is the same as stat() for Windows // lstat is the same as stat() for Windows.
@[inline] @[inline]
pub fn lstat(path string) !Stat { pub fn lstat(path string) !Stat {
return stat(path) return stat(path)
} }
// get_filetype returns the FileType from the Stat struct // get_filetype returns the FileType from the Stat struct.
pub fn (st Stat) get_filetype() FileType { pub fn (st Stat) get_filetype() FileType {
match st.mode & u32(C.S_IFMT) { match st.mode & u32(C.S_IFMT) {
u32(C.S_IFDIR) { u32(C.S_IFDIR) {
@ -47,8 +45,8 @@ pub fn (st Stat) get_filetype() FileType {
} }
} }
// get_mode returns the file type and permissions (readable, writable, executable) // get_mode returns the file type and permissions (readable, writable, executable) in owner/group/others format.
// in owner/group/others format, however, they will all be the same for Windows // Note: they will all be the same for Windows.
pub fn (st Stat) get_mode() FileMode { pub fn (st Stat) get_mode() FileMode {
return FileMode{ return FileMode{
typ: st.get_filetype() typ: st.get_filetype()
@ -92,7 +90,7 @@ pub fn is_link(path string) bool {
return int(attr) != int(C.INVALID_FILE_ATTRIBUTES) && (attr & 0x400) != 0 return int(attr) != int(C.INVALID_FILE_ATTRIBUTES) && (attr & 0x400) != 0
} }
// kind_of_existing_path identifies whether path is a file, directory, or link // kind_of_existing_path identifies whether path is a file, directory, or link.
fn kind_of_existing_path(path string) PathKind { fn kind_of_existing_path(path string) PathKind {
mut res := PathKind{} mut res := PathKind{}
attr := C.GetFileAttributesW(path.to_wide()) attr := C.GetFileAttributesW(path.to_wide())

View file

@ -6,12 +6,10 @@ import strings
#include <process.h> #include <process.h>
#include <sys/utime.h> #include <sys/utime.h>
// path_separator is the platform specific separator string, used between the folders // path_separator is the platform specific separator string, used between the folders, and filenames in a path. It is '/' on POSIX, and '\\' on Windows.
// and filenames in a path. It is '/' on POSIX, and '\\' on Windows.
pub const path_separator = '\\' pub const path_separator = '\\'
// path_delimiter is the platform specific delimiter string, used between the paths // path_delimiter is the platform specific delimiter string, used between the paths in environment variables like PATH. It is ':' on POSIX, and ';' on Windows.
// in environment variables like PATH. It is ':' on POSIX, and ';' on Windows.
pub const path_delimiter = ';' pub const path_delimiter = ';'
// path_devnull is a platform-specific file path of the null device. // path_devnull is a platform-specific file path of the null device.
@ -502,8 +500,7 @@ pub fn loginname() !string {
return unsafe { string_from_wide(&loginname[0]) } return unsafe { string_from_wide(&loginname[0]) }
} }
// ensure_folder_is_writable checks that `folder` exists, and is writable to the process // ensure_folder_is_writable checks that `folder` exists, and is writable to the process, by creating an empty file in it, then deleting it.
// by creating an empty file in it, then deleting it.
pub fn ensure_folder_is_writable(folder string) ! { pub fn ensure_folder_is_writable(folder string) ! {
if !exists(folder) { if !exists(folder) {
return error_with_code('`${folder}` does not exist', 1) return error_with_code('`${folder}` does not exist', 1)
@ -604,7 +601,7 @@ pub fn page_size() int {
return int(sinfo.dwPageSize) return int(sinfo.dwPageSize)
} }
// disk_usage returns disk usage of `path` // disk_usage returns disk usage of `path`.
pub fn disk_usage(path string) !DiskUsage { pub fn disk_usage(path string) !DiskUsage {
mut free_bytes_available_to_caller := u64(0) mut free_bytes_available_to_caller := u64(0)
mut total := u64(0) mut total := u64(0)

View file

@ -2,8 +2,8 @@ module os
import term.termios import term.termios
// input_password prompts the user for a password-like secret. It disables // input_password prompts the user for a password-like secret.
// the terminal echo during user input and resets it back to normal when done. // It disables the terminal echo during user input and resets it back to normal when done.
pub fn input_password(prompt string) !string { pub fn input_password(prompt string) !string {
if is_atty(1) <= 0 || getenv('TERM') == 'dumb' { if is_atty(1) <= 0 || getenv('TERM') == 'dumb' {
return error('Could not obtain password discretely.') return error('Could not obtain password discretely.')

View file

@ -2,8 +2,8 @@ module os
#include <windows.h> #include <windows.h>
// input_password prompts the user for a password-like secret. It disables // input_password prompts the user for a password-like secret.
// the terminal echo during user input and resets it back to normal when done. // It disables the terminal echo during user input and resets it back to normal when done.
pub fn input_password(prompt string) !string { pub fn input_password(prompt string) !string {
if is_atty(1) <= 0 || getenv('TERM') == 'dumb' { if is_atty(1) <= 0 || getenv('TERM') == 'dumb' {
return error('Could not obtain password discretely.') return error('Could not obtain password discretely.')

View file

@ -145,8 +145,8 @@ pub fn (mut p Process) stdin_write(s string) {
p._write_to(.stdin, s) p._write_to(.stdin, s)
} }
// stdout_slurp will read from the stdout pipe, and will block until it either // stdout_slurp will read from the stdout pipe.
// reads all the data, or until the pipe is closed (end of file). // It will block until it either reads all the data, or until the pipe is closed (end of file).
pub fn (mut p Process) stdout_slurp() string { pub fn (mut p Process) stdout_slurp() string {
p._check_redirection_call(@METHOD) p._check_redirection_call(@METHOD)
res := p._slurp_from(.stdout) res := p._slurp_from(.stdout)
@ -156,8 +156,8 @@ pub fn (mut p Process) stdout_slurp() string {
return res return res
} }
// stderr_slurp will read from the stderr pipe, and will block until it either // stderr_slurp will read from the stderr pipe.
// reads all the data, or until the pipe is closed (end of file). // It will block until it either reads all the data, or until the pipe is closed (end of file).
pub fn (mut p Process) stderr_slurp() string { pub fn (mut p Process) stderr_slurp() string {
p._check_redirection_call(@METHOD) p._check_redirection_call(@METHOD)
res := p._slurp_from(.stderr) res := p._slurp_from(.stderr)

View file

@ -4,7 +4,7 @@ $if js_node {
#const $child_process = require('child_process') #const $child_process = require('child_process')
} }
// new_process - create a new process descriptor // new_process - create a new process descriptor.
// Note: new does NOT start the new process. // Note: new does NOT start the new process.
// That is done because you may want to customize it first, // That is done because you may want to customize it first,
// by calling different set_ methods on it. // by calling different set_ methods on it.

View file

@ -34,7 +34,7 @@ pub mut:
create_no_window bool // sets a value indicating whether to start the process in a new window, The default is false; used only by the windows implementation create_no_window bool // sets a value indicating whether to start the process in a new window, The default is false; used only by the windows implementation
} }
// new_process - create a new process descriptor // new_process - create a new process descriptor.
// Note: new does NOT start the new process. // Note: new does NOT start the new process.
// That is done because you may want to customize it first, // That is done because you may want to customize it first,
// by calling different set_ methods on it. // by calling different set_ methods on it.
@ -46,7 +46,7 @@ pub fn new_process(filename string) &Process {
} }
} }
// set_args - set the arguments for the new process // set_args - set the arguments for the new process.
pub fn (mut p Process) set_args(pargs []string) { pub fn (mut p Process) set_args(pargs []string) {
if p.status != .not_started { if p.status != .not_started {
return return
@ -55,7 +55,7 @@ pub fn (mut p Process) set_args(pargs []string) {
return return
} }
// set_work_folder - set the initial working folder for the new process // set_work_folder - set the initial working folder for the new process.
// If you do not set it, it will reuse the current working folder of the parent process. // If you do not set it, it will reuse the current working folder of the parent process.
pub fn (mut p Process) set_work_folder(path string) { pub fn (mut p Process) set_work_folder(path string) {
if p.status != .not_started { if p.status != .not_started {
@ -65,7 +65,7 @@ pub fn (mut p Process) set_work_folder(path string) {
return return
} }
// set_environment - set a custom environment variable mapping for the new process // set_environment - set a custom environment variable mapping for the new process.
pub fn (mut p Process) set_environment(envs map[string]string) { pub fn (mut p Process) set_environment(envs map[string]string) {
if p.status != .not_started { if p.status != .not_started {
return return

View file

@ -24,7 +24,7 @@ pub fn signal_opt(signum Signal, handler SignalHandler) !SignalHandler {
fn ignore_signal_handler(_signal Signal) { fn ignore_signal_handler(_signal Signal) {
} }
// signal_ignore to mask system signals, e.g.: signal_ignore(.pipe, .urg, ...) // signal_ignore to mask system signals, e.g.: signal_ignore(.pipe, .urg, ...).
pub fn signal_ignore(args ...Signal) { pub fn signal_ignore(args ...Signal) {
if is_main_thread() { if is_main_thread() {
// for main thread. // for main thread.

View file

@ -13,8 +13,7 @@ const max_id_length = 32
// ~22k hosts before 50% chance of initial counter collision // ~22k hosts before 50% chance of initial counter collision
const max_session_count = 476782367 const max_session_count = 476782367
// Cuid2Generator Secure, collision-resistant ids optimized for horizontal // Cuid2Generator can be used to get secure, collision-resistant ids optimized for horizontal scaling and performance. Next generation UUIDs.
// scaling and performance. Next generation UUIDs.
pub struct Cuid2Generator { pub struct Cuid2Generator {
mut: mut:
// A counter that will be used to affect the entropy of // A counter that will be used to affect the entropy of
@ -83,13 +82,13 @@ pub fn (mut g Cuid2Generator) cuid2() string {
return hash_digest return hash_digest
} }
// next Generate a new cuid2 UUID. // next generates a new cuid2 UUID.
// It is an alias to function `cuid2()` // It is an alias to function `cuid2()`
pub fn (mut g Cuid2Generator) next() ?string { pub fn (mut g Cuid2Generator) next() ?string {
return g.cuid2() return g.cuid2()
} }
// is_cuid Checks whether a given `cuid` has a valid form and length // is_cuid checks whether a given `cuid` has a valid form and length.
pub fn is_cuid(cuid string) bool { pub fn is_cuid(cuid string) bool {
if cuid.len < min_id_length || cuid.len > max_id_length { if cuid.len < min_id_length || cuid.len > max_id_length {
return false return false

View file

@ -8,7 +8,7 @@ import rand.buffer
pub const seed_len = 1 pub const seed_len = 1
// MuslRNG ported from https://git.musl-libc.org/cgit/musl/tree/src/prng/rand_r.c // MuslRNG ported from https://git.musl-libc.org/cgit/musl/tree/src/prng/rand_r.c .
pub struct MuslRNG { pub struct MuslRNG {
buffer.PRNGBuffer buffer.PRNGBuffer
mut: mut:

View file

@ -8,7 +8,7 @@ import rand.buffer
pub const seed_len = 4 pub const seed_len = 4
// PCG32RNG ported from http://www.pcg-random.org/download.html, // PCG32RNG is ported from http://www.pcg-random.org/download.html .
// https://github.com/imneme/pcg-c-basic/blob/master/pcg_basic.c, and // https://github.com/imneme/pcg-c-basic/blob/master/pcg_basic.c, and
// https://github.com/imneme/pcg-c-basic/blob/master/pcg_basic.h // https://github.com/imneme/pcg-c-basic/blob/master/pcg_basic.h
pub struct PCG32RNG { pub struct PCG32RNG {

View file

@ -2,7 +2,7 @@ module rand
import time import time
// uuid_v4 generates a random (v4) UUID // uuid_v4 generates a random (v4) UUID.
// See https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random) // See https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
// See https://datatracker.ietf.org/doc/html/rfc9562#name-uuid-version-4 // See https://datatracker.ietf.org/doc/html/rfc9562#name-uuid-version-4
pub fn uuid_v4() string { pub fn uuid_v4() string {
@ -59,7 +59,7 @@ fn internal_uuid(version u8, rand_1 u64, rand_2 u64) string {
} }
} }
// uuid_v7 generates a time-ordered (v7) UUID // uuid_v7 generates a time-ordered (v7) UUID.
// See https://datatracker.ietf.org/doc/html/rfc9562#name-uuid-version-7 // See https://datatracker.ietf.org/doc/html/rfc9562#name-uuid-version-7
pub fn uuid_v7() string { pub fn uuid_v7() string {
timestamp_48 := u64(time.now().unix_milli()) << 16 timestamp_48 := u64(time.now().unix_milli()) << 16

View file

@ -9,8 +9,8 @@ import rand.config
import rand.wyrand import rand.wyrand
import time import time
// PRNG is a common interface for all PRNGs that can be used seamlessly with the rand // PRNG is a common interface for all PRNGs that can be used seamlessly with the rand modules's API.
// modules's API. It defines all the methods that a PRNG (in the vlib or custom made) must // It defines all the methods that a PRNG (in the vlib or custom made) must
// implement in order to ensure that _all_ functions can be used with the generator. // implement in order to ensure that _all_ functions can be used with the generator.
pub interface PRNG { pub interface PRNG {
mut: mut:
@ -36,7 +36,7 @@ pub fn (mut rng PRNG) bytes(bytes_needed int) ![]u8 {
return buffer return buffer
} }
// read fills in `buf` with a maximum of `buf.len` random bytes // read fills in `buf` with a maximum of `buf.len` random bytes.
pub fn (mut rng PRNG) read(mut buf []u8) { pub fn (mut rng PRNG) read(mut buf []u8) {
read_internal(mut rng, mut buf) read_internal(mut rng, mut buf)
} }
@ -358,7 +358,7 @@ pub fn (mut rng PRNG) ulid_at_millisecond(unix_time_milli u64) string {
return internal_ulid_at_millisecond(mut rng, unix_time_milli) return internal_ulid_at_millisecond(mut rng, unix_time_milli)
} }
// string_from_set returns a string of length `len` containing random characters sampled from the given `charset` // string_from_set returns a string of length `len` containing random characters sampled from the given `charset`.
pub fn (mut rng PRNG) string_from_set(charset string, len int) string { pub fn (mut rng PRNG) string_from_set(charset string, len int) string {
return internal_string_from_set(mut rng, charset, len) return internal_string_from_set(mut rng, charset, len)
} }
@ -392,16 +392,16 @@ pub fn (mut rng PRNG) bernoulli(p f64) !bool {
return rng.f64() <= p return rng.f64() <= p
} }
// normal returns a normally distributed pseudorandom f64 with mean `mu` and standard // normal returns a normally distributed pseudorandom f64 with mean `mu` and standard deviation `sigma`.
// deviation `sigma`. By default, `mu` is 0.0 and `sigma` is 1.0. // By default, `mu` is 0.0 and `sigma` is 1.0.
// 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 with mean `mu` and standard // normal_pair returns a pair of normally distributed pseudorandom f64 with mean `mu` and standard deviation `sigma`.
// deviation `sigma`. By default, `mu` is 0.0 and `sigma` is 1.0. // By default, `mu` is 0.0 and `sigma` is 1.0.
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')
@ -425,8 +425,7 @@ pub fn (mut rng PRNG) normal_pair(conf config.NormalConfigStruct) !(f64, f64) {
return error('Implementation error. Please file an issue.') return error('Implementation error. Please file an issue.')
} }
// 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.')
@ -440,8 +439,8 @@ pub fn (mut rng PRNG) binomial(n int, p f64) !int {
return count return count
} }
// exponential returns an exponentially distributed random number with the rate parameter // exponential returns an exponentially distributed random number with the rate parameter lambda.
// lambda. It is expected that lambda is positive. // It is expected that lambda is positive.
pub fn (mut rng PRNG) exponential(lambda f64) f64 { pub fn (mut rng PRNG) exponential(lambda f64) f64 {
if lambda <= 0 { if lambda <= 0 {
panic('The rate (lambda) must be positive.') panic('The rate (lambda) must be positive.')
@ -530,8 +529,8 @@ pub fn get_current_rng() &PRNG {
return default_rng return default_rng
} }
// set_rng changes the default RNG from wyrand.WyRandRNG (or whatever the last RNG was) to the one // set_rng changes the default RNG from wyrand.WyRandRNG (or whatever the last RNG was).
// provided by the user. Note that this new RNG must be seeded manually with a constant seed or the // Note that this new RNG must be seeded manually with a constant seed or the
// `seed.time_seed_array()` method. Also, it is recommended to store the old RNG in a variable and // `seed.time_seed_array()` method. Also, it is recommended to store the old RNG in a variable and
// should be restored if work with the custom RNG is complete. It is not necessary to restore if the // should be restored if work with the custom RNG is complete. It is not necessary to restore if the
// program terminates soon afterwards. // program terminates soon afterwards.
@ -539,8 +538,8 @@ pub fn set_rng(rng &PRNG) {
default_rng = unsafe { rng } default_rng = unsafe { rng }
} }
// seed sets the given array of `u32` values as the seed for the `default_rng`. The default_rng is // seed sets the given array of `u32` values as the seed for the `default_rng`.
// an instance of WyRandRNG which takes 2 u32 values. When using a custom RNG, make sure to use // The default_rng is an instance of WyRandRNG which takes 2 u32 values. When using a custom RNG, make sure to use
// the correct number of u32s. // the correct number of u32s.
pub fn seed(seed []u32) { pub fn seed(seed []u32) {
default_rng.seed(seed) default_rng.seed(seed)
@ -653,8 +652,7 @@ pub fn f32() f32 {
return default_rng.f32() return default_rng.f32()
} }
// f32cp returns a uniformly distributed 32-bit floating point in range `[0, 1)` // f32cp returns a uniformly distributed 32-bit floating point in range `[0, 1)` with full precision mantissa.
// with full precision mantissa.
pub fn f32cp() f32 { pub fn f32cp() f32 {
return default_rng.f32cp() return default_rng.f32cp()
} }
@ -664,8 +662,7 @@ pub fn f64() f64 {
return default_rng.f64() return default_rng.f64()
} }
// f64 returns a uniformly distributed 64-bit floating point in range `[0, 1)` // f64 returns a uniformly distributed 64-bit floating point in range `[0, 1)` with full precision mantissa.
// with full precision mantissa.
pub fn f64cp() f64 { pub fn f64cp() f64 {
return default_rng.f64cp() return default_rng.f64cp()
} }
@ -690,12 +687,12 @@ 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)
} }
// read fills in `buf` a maximum of `buf.len` random bytes // read fills in `buf` a maximum of `buf.len` random bytes.
pub fn read(mut buf []u8) { pub fn read(mut buf []u8) {
read_internal(mut default_rng, mut buf) read_internal(mut default_rng, mut buf)
} }
@ -719,7 +716,7 @@ pub fn ulid_at_millisecond(unix_time_milli u64) string {
return default_rng.ulid_at_millisecond(unix_time_milli) return default_rng.ulid_at_millisecond(unix_time_milli)
} }
// string_from_set returns a string of length `len` containing random characters sampled from the given `charset` // string_from_set returns a string of length `len` containing random characters sampled from the given `charset`.
pub fn string_from_set(charset string, len int) string { pub fn string_from_set(charset string, len int) string {
return default_rng.string_from_set(charset, len) return default_rng.string_from_set(charset, len)
} }
@ -745,9 +742,9 @@ pub fn ascii(len int) string {
return string_from_set(ascii_chars, len) return string_from_set(ascii_chars, len)
} }
// shuffle randomly permutates the elements in `a`. The range for shuffling is // shuffle randomly permutates the elements in `a`.
// optional and the entire array is shuffled by default. Leave the end as 0 to // The range for shuffling is optional and the entire array is shuffled by default.
// shuffle all elements until the end. // Leave the end as 0 to 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_)!
} }
@ -782,27 +779,26 @@ pub fn bernoulli(p f64) !bool {
return default_rng.bernoulli(p) return default_rng.bernoulli(p)
} }
// normal returns a normally distributed pseudorandom f64 with mean `mu` and standard // normal returns a normally distributed pseudorandom f64 with mean `mu` and standard deviation `sigma`.
// deviation `sigma`. By default, `mu` is 0.0 and `sigma` is 1.0. // By default, `mu` is 0.0 and `sigma` is 1.0.
// 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(config_ config.NormalConfigStruct) !f64 { pub fn normal(config_ config.NormalConfigStruct) !f64 {
return default_rng.normal(config_) return default_rng.normal(config_)
} }
// normal_pair returns a pair of normally distributed pseudorandom f64 with mean `mu` and standard // normal_pair returns a pair of normally distributed pseudorandom f64 with mean `mu` and standard deviation `sigma`.
// deviation `sigma`. By default, `mu` is 0.0 and `sigma` is 1.0. // By default, `mu` is 0.0 and `sigma` is 1.0.
pub fn normal_pair(config_ config.NormalConfigStruct) !(f64, f64) { pub fn normal_pair(config_ config.NormalConfigStruct) !(f64, f64) {
return default_rng.normal_pair(config_) return default_rng.normal_pair(config_)
} }
// 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)
} }
// exponential returns an exponentially distributed random number with the rate parameter // exponential returns an exponentially distributed random number with the rate parameter `lambda`.
// lambda. It is expected that lambda is positive. // It is expected that lambda is positive.
pub fn exponential(lambda f64) f64 { pub fn exponential(lambda f64) f64 {
return default_rng.exponential(lambda) return default_rng.exponential(lambda)
} }

View file

@ -8,7 +8,7 @@ import rand.buffer
pub const seed_len = 2 pub const seed_len = 2
// SplitMix64RNG ported from http://xoshiro.di.unimi.it/splitmix64.c // SplitMix64RNG is ported from http://xoshiro.di.unimi.it/splitmix64.c .
pub struct SplitMix64RNG { pub struct SplitMix64RNG {
buffer.PRNGBuffer buffer.PRNGBuffer
mut: mut:
@ -17,8 +17,7 @@ mut:
buffer u64 buffer u64
} }
// seed sets the seed of the accepting SplitMix64RNG to the given data // seed sets the seed of the accepting SplitMix64RNG to the given data in little-endian format (i.e. lower 32 bits are in [0] and higher 32 bits in [1]).
// in little-endian format (i.e. lower 32 bits are in [0] and higher 32 bits in [1]).
pub fn (mut rng SplitMix64RNG) seed(seed_data []u32) { pub fn (mut rng SplitMix64RNG) seed(seed_data []u32) {
if seed_data.len != 2 { if seed_data.len != 2 {
eprintln('SplitMix64RNG needs 2 32-bit unsigned integers as the seed.') eprintln('SplitMix64RNG needs 2 32-bit unsigned integers as the seed.')

View file

@ -12,7 +12,7 @@ fn rotl(x u64, k int) u64 {
return (x << k) | (x >> (64 - k)) return (x << k) | (x >> (64 - k))
} }
// XOROS128PPRNG ported from https://prng.di.unimi.it/xoroshiro128plusplus.c // XOROS128PPRNG is ported from https://prng.di.unimi.it/xoroshiro128plusplus.c .
pub struct XOROS128PPRNG { pub struct XOROS128PPRNG {
buffer.PRNGBuffer buffer.PRNGBuffer
mut: mut:

View file

@ -54,22 +54,19 @@ pub fn build(major int, minor int, patch int) Version {
return Version{major, minor, patch, '', ''} return Version{major, minor, patch, '', ''}
} }
// * Transformation.
// increment returns a `Version` structure with incremented values. // increment returns a `Version` structure with incremented values.
pub fn (ver Version) increment(typ Increment) Version { pub fn (ver Version) increment(typ Increment) Version {
return increment_version(ver, typ) return increment_version(ver, typ)
} }
// * Comparison. // satisfies returns `true` if the `input` expression can be validated to `true` when run against this `Version`.
// satisfies returns `true` if the `input` expression can be validated to `true`
// when run against this `Version`.
// Example: assert semver.build(1,0,0).satisfies('<=2.0.0') == true // Example: assert semver.build(1,0,0).satisfies('<=2.0.0') == true
// Example: assert semver.build(1,0,0).satisfies('>=2.0.0') == false // Example: assert semver.build(1,0,0).satisfies('>=2.0.0') == false
pub fn (ver Version) satisfies(input string) bool { pub fn (ver Version) satisfies(input string) bool {
return version_satisfies(ver, input) return version_satisfies(ver, input)
} }
// == checks if `v1` is equal to `v2` // == checks if `v1` is equal to `v2`.
pub fn (v1 Version) == (v2 Version) bool { pub fn (v1 Version) == (v2 Version) bool {
return compare_eq(v1, v2) return compare_eq(v1, v2)
} }

View file

@ -9,7 +9,7 @@ module strings
// constantly string concatenation. // constantly string concatenation.
pub type Builder = []u8 pub type Builder = []u8
// new_builder returns a new string builder, with an initial capacity of `initial_size` // new_builder returns a new string builder, with an initial capacity of `initial_size`.
pub fn new_builder(initial_size int) Builder { pub fn new_builder(initial_size int) Builder {
mut res := Builder([]u8{cap: initial_size}) mut res := Builder([]u8{cap: initial_size})
unsafe { res.flags.set(.noslices) } unsafe { res.flags.set(.noslices) }
@ -47,7 +47,7 @@ pub fn (mut b Builder) write_rune(r rune) {
unsafe { b.push_many(res.str, res.len) } unsafe { b.push_many(res.str, res.len) }
} }
// write_runes appends all the given runes to the accumulated buffer // write_runes appends all the given runes to the accumulated buffer.
pub fn (mut b Builder) write_runes(runes []rune) { pub fn (mut b Builder) write_runes(runes []rune) {
mut buffer := [5]u8{} mut buffer := [5]u8{}
for r in runes { for r in runes {
@ -97,8 +97,7 @@ pub fn (mut b Builder) write_decimal(n i64) {
unsafe { b.write_ptr(&buf[i + 1], 24 - i) } unsafe { b.write_ptr(&buf[i + 1], 24 - i) }
} }
// write implements the io.Writer interface, that is why it // write implements the io.Writer interface, that is why it returns how many bytes were written to the string builder.
// it returns how many bytes were written to the string builder.
pub fn (mut b Builder) write(data []u8) !int { pub fn (mut b Builder) write(data []u8) !int {
if data.len == 0 { if data.len == 0 {
return 0 return 0
@ -138,7 +137,7 @@ pub fn (mut b Builder) write_string(s string) {
// b.buf << []u8(s) // TODO // b.buf << []u8(s) // TODO
} }
// write_string2 appends the strings `s1` and `s2` to the buffer // write_string2 appends the strings `s1` and `s2` to the buffer.
@[inline] @[inline]
pub fn (mut b Builder) write_string2(s1 string, s2 string) { pub fn (mut b Builder) write_string2(s1 string, s2 string) {
if s1.len != 0 { if s1.len != 0 {
@ -149,7 +148,7 @@ pub fn (mut b Builder) write_string2(s1 string, s2 string) {
} }
} }
// go_back discards the last `n` bytes from the buffer // go_back discards the last `n` bytes from the buffer.
pub fn (mut b Builder) go_back(n int) { pub fn (mut b Builder) go_back(n int) {
b.trim(b.len - n) b.trim(b.len - n)
} }
@ -165,7 +164,7 @@ pub fn (b &Builder) spart(start_pos int, n int) string {
} }
} }
// cut_last cuts the last `n` bytes from the buffer and returns them // cut_last cuts the last `n` bytes from the buffer and returns them.
pub fn (mut b Builder) cut_last(n int) string { pub fn (mut b Builder) cut_last(n int) string {
cut_pos := b.len - n cut_pos := b.len - n
res := b.spart(cut_pos, n) res := b.spart(cut_pos, n)
@ -183,7 +182,7 @@ pub fn (mut b Builder) cut_to(pos int) string {
return b.cut_last(b.len - pos) return b.cut_last(b.len - pos)
} }
// go_back_to resets the buffer to the given position `pos` // go_back_to resets the buffer to the given position `pos`.
// Note: pos should be < than the existing buffer length. // Note: pos should be < than the existing buffer length.
pub fn (mut b Builder) go_back_to(pos int) { pub fn (mut b Builder) go_back_to(pos int) {
b.trim(pos) b.trim(pos)
@ -245,7 +244,7 @@ pub fn (mut b Builder) str() string {
return s return s
} }
// ensure_cap ensures that the buffer has enough space for at least `n` bytes by growing the buffer if necessary // ensure_cap ensures that the buffer has enough space for at least `n` bytes by growing the buffer if necessary.
pub fn (mut b Builder) ensure_cap(n int) { pub fn (mut b Builder) ensure_cap(n int) {
// code adapted from vlib/builtin/array.v // code adapted from vlib/builtin/array.v
if n <= b.cap { if n <= b.cap {

View file

@ -79,7 +79,7 @@ pub fn (mut b Builder) go_back_to(pos int) {
b.trim(pos) b.trim(pos)
} }
// go_back discards the last `n` bytes from the buffer // go_back discards the last `n` bytes from the buffer.
pub fn (mut b Builder) go_back(n int) { pub fn (mut b Builder) go_back(n int) {
b.trim(b.len - n) b.trim(b.len - n)
} }

View file

@ -66,8 +66,7 @@ pub fn levenshtein_distance(a string, b string) int {
return row[a.len] return row[a.len]
} }
// levenshtein_distance_percentage uses the Levenshtein Distance algorithm to calculate // levenshtein_distance_percentage uses the Levenshtein Distance algorithm to calculate how similar two strings are as a percentage (higher is closer).
// how similar two strings are as a percentage (higher is closer).
pub fn levenshtein_distance_percentage(a string, b string) f32 { pub fn levenshtein_distance_percentage(a string, b string) f32 {
d := levenshtein_distance(a, b) d := levenshtein_distance(a, b)
l := if a.len >= b.len { a.len } else { b.len } l := if a.len >= b.len { a.len } else { b.len }
@ -124,8 +123,7 @@ pub fn hamming_distance(a string, b string) int {
return diff_count return diff_count
} }
// hamming_similarity uses the Hamming Distance algorithm to calculate // hamming_similarity uses the Hamming Distance algorithm to calculate the distance between two strings `a` and `b`.
// the distance between two strings `a` and `b`.
// It returns a coefficient between 0.0 (not similar) and 1.0 (exact match). // It returns a coefficient between 0.0 (not similar) and 1.0 (exact match).
pub fn hamming_similarity(a string, b string) f32 { pub fn hamming_similarity(a string, b string) f32 {
l := max2(a.len, b.len) l := max2(a.len, b.len)

View file

@ -47,8 +47,7 @@ pub fn find_between_pair_u8(input string, start u8, end u8) string {
return '' return ''
} }
// find_between_pair_rune returns the string found between the pair of marks defined // find_between_pair_rune returns the string found between the pair of marks defined by `start` and `end`.
// by `start` and `end`.
// As opposed to the `find_between`, `all_after*`, `all_before*` methods defined on the // As opposed to the `find_between`, `all_after*`, `all_before*` methods defined on the
// `string` type, this function can extract content between *nested* marks in `input`. // `string` type, this function can extract content between *nested* marks in `input`.
// If `start` and `end` marks are nested in `input`, the characters // If `start` and `end` marks are nested in `input`, the characters
@ -83,8 +82,7 @@ pub fn find_between_pair_rune(input string, start rune, end rune) string {
return '' return ''
} }
// find_between_pair_string returns the string found between the pair of marks defined // find_between_pair_string returns the string found between the pair of marks defined by `start` and `end`.
// by `start` and `end`.
// As opposed to the `find_between`, `all_after*`, `all_before*` methods defined on the // As opposed to the `find_between`, `all_after*`, `all_before*` methods defined on the
// `string` type, this function can extract content between *nested* marks in `input`. // `string` type, this function can extract content between *nested* marks in `input`.
// If `start` and `end` marks are nested in `input`, the characters // If `start` and `end` marks are nested in `input`, the characters

View file

@ -1,8 +1,7 @@
module textscanner module textscanner
// TextScanner simplifies writing small scanners/parsers // TextScanner simplifies writing small scanners/parsers.
// by providing safe methods to scan texts character by // It helps by providing safe methods to scan texts character by character, peek for the next characters, go back, etc.
// character, peek for the next characters, go back, etc.
pub struct TextScanner { pub struct TextScanner {
pub: pub:
input string input string
@ -164,14 +163,14 @@ pub fn (mut ss TextScanner) current() int {
return -1 return -1
} }
// reset resets the internal state of the scanner // reset resets the internal state of the scanner.
// After calling .reset(), .next() will start reading // After calling .reset(), .next() will start reading
// again from the start of the input text. // again from the start of the input text.
pub fn (mut ss TextScanner) reset() { pub fn (mut ss TextScanner) reset() {
ss.pos = 0 ss.pos = 0
} }
// goto_end has the same effect as `for ts.next() != -1 {}` // goto_end has the same effect as `for ts.next() != -1 {}`.
// i.e. after calling .goto_end(), the scanner will be at // i.e. after calling .goto_end(), the scanner will be at
// the end of the input text. Further .next() calls will // the end of the input text. Further .next() calls will
// return -1, unless you go back. // return -1, unless you go back.

View file

@ -5,16 +5,15 @@ module term
import strings import strings
// format_esc produces an ANSI escape code, for selecting the graphics rendition of the following // format_esc produces an ANSI escape code, for selecting the graphics rendition of the following text.
// text. Each of the attributes that can be passed in `code`, separated by `;`, will be in effect, // Each of the attributes that can be passed in `code`, separated by `;`, will be in effect,
// until the terminal encounters another SGR ANSI escape code. For more details about the different // until the terminal encounters another SGR ANSI escape code. For more details about the different
// codes, and their meaning, see: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters // codes, and their meaning, see: https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters
pub fn format_esc(code string) string { pub fn format_esc(code string) string {
return '\x1b[${code}m' return '\x1b[${code}m'
} }
// format returns ANSI escape coded `msg` formatted with a preceding // format returns ANSI escape coded `msg` formatted with a preceding `open` and a succeeding `close`.
// `open` and a succeeding `close`.
// For instance, `format('hi', '9', '29')` returns `'\x1b[9mhi\x1b[29m'`, // For instance, `format('hi', '9', '29')` returns `'\x1b[9mhi\x1b[29m'`,
// or 'hi' with strikethrough, where `'\x1b[9m'` represents // or 'hi' with strikethrough, where `'\x1b[9m'` represents
// crossed out/strikethrough text and `'\x1b[29m'` turns off strikethrough. // crossed out/strikethrough text and `'\x1b[29m'` turns off strikethrough.
@ -22,8 +21,7 @@ pub fn format(msg string, open string, close string) string {
return '\x1b[${open}m${msg}\x1b[${close}m' return '\x1b[${open}m${msg}\x1b[${close}m'
} }
// format_rgb returns ANSI escape coded `msg` formatted with a preceding // format_rgb returns ANSI escape coded `msg` formatted with a preceding `open`, a succeeding `close` and the provided RGB colors `r`, `g`, and `b`.
// `open`, a succeeding `close` and the provided RGB colors `r`, `g`, and `b`.
pub fn format_rgb(r int, g int, b int, msg string, open string, close string) string { pub fn format_rgb(r int, g int, b int, msg string, open string, close string) string {
return '\x1b[${open};2;${r};${g};${b}m${msg}\x1b[${close}m' return '\x1b[${open};2;${r};${g};${b}m${msg}\x1b[${close}m'
} }
@ -42,14 +40,14 @@ pub fn bg_rgb(r int, g int, b int, msg string) string {
return format_rgb(r, g, b, msg, '48', '49') return format_rgb(r, g, b, msg, '48', '49')
} }
// hex returns the `msg` with the foreground in the specified `hex` color // hex returns the `msg` with the foreground in the specified `hex` color.
// For example, `rgb(255, 'hi')` returns the `'hi'` string in // For example, `rgb(255, 'hi')` returns the `'hi'` string in
// blue color, which is `(0, 0, 255)` in RGB. // blue color, which is `(0, 0, 255)` in RGB.
pub fn hex(hex int, msg string) string { pub fn hex(hex int, msg string) string {
return format_rgb(hex >> 16, (hex >> 8) & 0xFF, hex & 0xFF, msg, '38', '39') return format_rgb(hex >> 16, (hex >> 8) & 0xFF, hex & 0xFF, msg, '38', '39')
} }
// hex returns the `msg` with the background in the specified `hex` color // hex returns the `msg` with the background in the specified `hex` color.
// For example, `bg_rgb(255, 'hi')` returns the `'hi'` string in // For example, `bg_rgb(255, 'hi')` returns the `'hi'` string in
// a background of blue color, which is `(0, 0, 255)` in RGB. // a background of blue color, which is `(0, 0, 255)` in RGB.
pub fn bg_hex(hex int, msg string) string { pub fn bg_hex(hex int, msg string) string {
@ -272,8 +270,7 @@ pub fn bright_bg_white(msg string) string {
return format(msg, '107', '49') return format(msg, '107', '49')
} }
// highlight_command highlights the command with an on-brand background // highlight_command highlights the command with an on-brand background to make CLI commands immediately recognizable.
// to make CLI commands immediately recognizable.
pub fn highlight_command(command string) string { pub fn highlight_command(command string) string {
return bright_white(bg_cyan(' ${command} ')) return bright_white(bg_cyan(' ${command} '))
} }

View file

@ -19,7 +19,8 @@ pub fn set_cursor_position(c Coord) {
flush_stdout() flush_stdout()
} }
// n is number of cells // move the cursor relative to its current position.
// n is number of cells.
// direction: A is up / North // direction: A is up / North
// direction: B is down / South // direction: B is down / South
// direction: C is forward / East // direction: C is forward / East
@ -71,8 +72,7 @@ pub fn erase_tobeg() {
erase_display('1') erase_display('1')
} }
// erase_clear clears the entire terminal window and returns the cursor to the // erase_clear clears the entire terminal window and returns the cursor to the top left corner.
// top left corner.
pub fn erase_clear() { pub fn erase_clear() {
print('\033[H\033[J') print('\033[H\033[J')
flush_stdout() flush_stdout()
@ -99,8 +99,7 @@ pub fn erase_line_toend() {
erase_line('0') erase_line('0')
} }
// erase_line_tobeg erases from the start of the line to the cursor // erase_line_tobeg erases from the start of the line to the cursor position.
// position.
pub fn erase_line_tobeg() { pub fn erase_line_tobeg() {
erase_line('1') erase_line('1')
} }

View file

@ -7,7 +7,7 @@ import strings.textscanner
const default_columns_size = 80 const default_columns_size = 80
const default_rows_size = 25 const default_rows_size = 25
// Coord - used by term.get_cursor_position and term.set_cursor_position // Coord - used by term.get_cursor_position and term.set_cursor_position.
pub struct Coord { pub struct Coord {
pub mut: pub mut:
x int x int
@ -17,8 +17,8 @@ pub mut:
__global can_show_color_on_stdout_cache = ?bool(none) __global can_show_color_on_stdout_cache = ?bool(none)
__global can_show_color_on_stderr_cache = ?bool(none) __global can_show_color_on_stderr_cache = ?bool(none)
// can_show_color_on_stdout returns true if colors are allowed in stdout; // can_show_color_on_stdout returns true, if colors are allowed in stdout.
// returns false otherwise. // It returns false otherwise.
pub fn can_show_color_on_stdout() bool { pub fn can_show_color_on_stdout() bool {
if status := can_show_color_on_stdout_cache { if status := can_show_color_on_stdout_cache {
return status return status
@ -28,8 +28,8 @@ pub fn can_show_color_on_stdout() bool {
return status return status
} }
// can_show_color_on_stderr returns true if colors are allowed in stderr; // can_show_color_on_stderr returns true, if colors are allowed in stderr.
// returns false otherwise. // It returns false otherwise.
pub fn can_show_color_on_stderr() bool { pub fn can_show_color_on_stderr() bool {
if status := can_show_color_on_stderr_cache { if status := can_show_color_on_stderr_cache {
return status return status
@ -39,7 +39,7 @@ pub fn can_show_color_on_stderr() bool {
return status return status
} }
// failed returns a bold white on red version of the string `s` // failed returns a bold white on red version of the string `s`.
// If colors are not allowed, returns the string `s` // If colors are not allowed, returns the string `s`
pub fn failed(s string) string { pub fn failed(s string) string {
if can_show_color_on_stdout() { if can_show_color_on_stdout() {
@ -72,8 +72,7 @@ pub fn warn_message(s string) string {
return s return s
} }
// colorize returns a colored string by running the specified `cfn` over // colorize returns a colored string by running the specified `cfn` over the message `s`, but only if colored stdout is supported by the terminal.
// the message `s`, only if colored stdout is supported by the terminal.
// Example: term.colorize(term.yellow, 'the message') // Example: term.colorize(term.yellow, 'the message')
pub fn colorize(cfn fn (string) string, s string) string { pub fn colorize(cfn fn (string) string, s string) string {
if can_show_color_on_stdout() { if can_show_color_on_stdout() {
@ -82,8 +81,7 @@ pub fn colorize(cfn fn (string) string, s string) string {
return s return s
} }
// ecolorize returns a colored string by running the specified `cfn` over // ecolorize returns a colored string by running the specified `cfn` over the message `s`, but only if colored stderr is supported by the terminal.
// the message `s`, only if colored stderr is supported by the terminal.
// Example: term.ecolorize(term.bright_red, 'the message') // Example: term.ecolorize(term.bright_red, 'the message')
pub fn ecolorize(cfn fn (string) string, s string) string { pub fn ecolorize(cfn fn (string) string, s string) string {
if can_show_color_on_stderr() { if can_show_color_on_stderr() {
@ -92,7 +90,7 @@ pub fn ecolorize(cfn fn (string) string, s string) string {
return s return s
} }
// strip_ansi removes any ANSI sequences in the `text` // strip_ansi removes any ANSI sequences in the `text`.
pub fn strip_ansi(text string) string { pub fn strip_ansi(text string) string {
// This is a port of https://github.com/kilobyte/colorized-logs/blob/master/ansi2txt.c // This is a port of https://github.com/kilobyte/colorized-logs/blob/master/ansi2txt.c
// \e, [, 1, m, a, b, c, \e, [, 2, 2, m => abc // \e, [, 1, m, a, b, c, \e, [, 2, 2, m => abc
@ -135,9 +133,8 @@ pub fn strip_ansi(text string) string {
return output.bytestr() return output.bytestr()
} }
// h_divider returns a horizontal divider line with a dynamic width, // h_divider returns a horizontal divider line with a dynamic width, that depends on the current terminal settings.
// that depends on the current terminal settings. // If an empty string is passed in, print enough spaces to make a new line.
// If an empty string is passed in, print enough spaces to make a new line
pub fn h_divider(divider string) string { pub fn h_divider(divider string) string {
cols, _ := get_terminal_size() cols, _ := get_terminal_size()
mut result := '' mut result := ''

View file

@ -26,7 +26,7 @@ pub fn get_terminal_size() (int, int) {
return int(w.ws_col), int(w.ws_row) return int(w.ws_col), int(w.ws_row)
} }
// get_cursor_position returns a Coord containing the current cursor position // get_cursor_position returns a Coord containing the current cursor position.
pub fn get_cursor_position() !Coord { pub fn get_cursor_position() !Coord {
if os.is_atty(1) <= 0 || os.getenv('TERM') == 'dumb' { if os.is_atty(1) <= 0 || os.getenv('TERM') == 'dumb' {
return Coord{0, 0} return Coord{0, 0}
@ -78,7 +78,7 @@ pub fn get_cursor_position() !Coord {
return Coord{x, y} return Coord{x, y}
} }
// set_terminal_title change the terminal title (usually that is the containing terminal window title) // set_terminal_title change the terminal title (usually that is the containing terminal window title).
pub fn set_terminal_title(title string) bool { pub fn set_terminal_title(title string) bool {
if os.is_atty(1) <= 0 || os.getenv('TERM') == 'dumb' { if os.is_atty(1) <= 0 || os.getenv('TERM') == 'dumb' {
return false return false
@ -90,7 +90,7 @@ pub fn set_terminal_title(title string) bool {
return true return true
} }
// set_tab_title changes the terminal *tab title*, for terminal emulators like Konsole, that support several tabs // set_tab_title changes the terminal *tab title*, for terminal emulators like Konsole, that support several tabs.
pub fn set_tab_title(title string) bool { pub fn set_tab_title(title string) bool {
if os.is_atty(1) <= 0 || os.getenv('TERM') == 'dumb' { if os.is_atty(1) <= 0 || os.getenv('TERM') == 'dumb' {
return false return false
@ -217,7 +217,7 @@ pub fn graphics_num_colors() u16 {
return buf.bytestr().u16() return buf.bytestr().u16()
} }
// enable_echo enable/disable echo input characters // enable_echo enable/disable echo input characters.
pub fn enable_echo(enable bool) { pub fn enable_echo(enable bool) {
mut state := termios.Termios{} mut state := termios.Termios{}
termios.tcgetattr(0, mut state) termios.tcgetattr(0, mut state)

View file

@ -72,7 +72,7 @@ pub fn get_terminal_size() (int, int) {
return default_columns_size, default_rows_size return default_columns_size, default_rows_size
} }
// get_cursor_position returns a Coord containing the current cursor position // get_cursor_position returns a Coord containing the current cursor position.
pub fn get_cursor_position() !Coord { pub fn get_cursor_position() !Coord {
mut res := Coord{} mut res := Coord{}
if os.is_atty(1) > 0 && os.getenv('TERM') != 'dumb' { if os.is_atty(1) > 0 && os.getenv('TERM') != 'dumb' {
@ -87,13 +87,13 @@ pub fn get_cursor_position() !Coord {
return res return res
} }
// set_terminal_title changes the terminal title // set_terminal_title changes the terminal title.
pub fn set_terminal_title(title string) bool { pub fn set_terminal_title(title string) bool {
wide_title := title.to_wide() wide_title := title.to_wide()
return C.SetConsoleTitle(wide_title) return C.SetConsoleTitle(wide_title)
} }
// set_tab_title changes the terminal *tab title*, for terminal emulators that do support several tabs // set_tab_title changes the terminal *tab title*, for terminal emulators that do support several tabs.
pub fn set_tab_title(title string) bool { pub fn set_tab_title(title string) bool {
// TODO: investigate, whether there is an API for changing just the tab title on windows yet. // TODO: investigate, whether there is an API for changing just the tab title on windows yet.
return set_terminal_title(title) return set_terminal_title(title)
@ -160,7 +160,7 @@ pub fn graphics_num_colors() u16 {
return 0 return 0
} }
// enable_echo enable/disable echo input characters // enable_echo enable/disable echo input characters.
pub fn enable_echo(enable bool) { pub fn enable_echo(enable bool) {
// no need under windows, use key_pressed func's echo // no need under windows, use key_pressed func's echo
} }

View file

@ -93,8 +93,7 @@ pub fn set_state(fd int, new_state Termios) int {
return tcsetattr(0, C.TCSANOW, mut x) return tcsetattr(0, C.TCSANOW, mut x)
} }
// disable_echo disables echoing characters as they are typed, // disable_echo disables echoing characters as they are typed, when that Termios state is later set with termios.set_state(fd,t).
// when that Termios state is later set with termios.set_state(fd,t)
pub fn (mut t Termios) disable_echo() { pub fn (mut t Termios) disable_echo() {
t.c_lflag &= invert(C.ECHO) t.c_lflag &= invert(C.ECHO)
} }

View file

@ -91,8 +91,7 @@ pub fn set_state(fd int, new_state Termios) int {
return tcsetattr(0, C.TCSANOW, mut x) return tcsetattr(0, C.TCSANOW, mut x)
} }
// disable_echo disables echoing characters as they are typed, // disable_echo disables echoing characters as they are typed, when that Termios state is later set with termios.set_state(fd,t).
// when that Termios state is later set with termios.set_state(fd,t)
pub fn (mut t Termios) disable_echo() { pub fn (mut t Termios) disable_echo() {
t.c_lflag &= invert(usize(C.ECHO)) t.c_lflag &= invert(usize(C.ECHO))
} }

View file

@ -8,7 +8,7 @@ type TcFlag = int
type Speed = int type Speed = int
type Cc = u8 type Cc = u8
// Termios definitions // Termios represents platform dependent flags representing the terminal state.
// Linux https://github.com/lattera/glibc/blob/master/sysdeps/unix/sysv/linux/bits/termios.h // Linux https://github.com/lattera/glibc/blob/master/sysdeps/unix/sysv/linux/bits/termios.h
// OpenBSD https://github.com/openbsd/src/blob/master/sys/sys/termios.h // OpenBSD https://github.com/openbsd/src/blob/master/sys/sys/termios.h
// FreeBSD https://web.mit.edu/freebsd/head/sys/sys/_termios.h // FreeBSD https://web.mit.edu/freebsd/head/sys/sys/_termios.h
@ -27,20 +27,18 @@ pub mut:
c_ospeed Speed c_ospeed Speed
} }
// flag provides a termios flag of the correct size // flag provides a termios flag of the correct size for the underlying C.termios structure.
// for the underlying C.termios structure
pub fn flag(value int) TcFlag { pub fn flag(value int) TcFlag {
return TcFlag(value) return TcFlag(value)
} }
// invert is a platform dependant way to bitwise NOT (~) TcFlag // invert is a platform dependant way to bitwise NOT (~) TcFlag as its length varies across platforms.
// as its length varies across platforms // It is only implemented for Unix like OSes.
// It is only implemented for Unix like OSes
pub fn invert(value TcFlag) TcFlag { pub fn invert(value TcFlag) TcFlag {
return TcFlag(~int(value)) return TcFlag(~int(value))
} }
// tcgetattr is an unsafe wrapper around C.termios and keeps its semantic // tcgetattr is an unsafe wrapper around C.termios and keeps its semantic.
// It is only implemented for Unix like OSes // It is only implemented for Unix like OSes
pub fn tcgetattr(fd int, mut t Termios) int { pub fn tcgetattr(fd int, mut t Termios) int {
$if wasm32_emscripten { $if wasm32_emscripten {
@ -51,14 +49,14 @@ pub fn tcgetattr(fd int, mut t Termios) int {
return 0 return 0
} }
// tcsetattr is an unsafe wrapper around C.termios and keeps its semantic // tcsetattr is an unsafe wrapper around C.termios and keeps its semantic.
// It is only implemented for Unix like OSes // It is only implemented for Unix like OSes.
pub fn tcsetattr(fd int, optional_actions int, mut t Termios) int { pub fn tcsetattr(fd int, optional_actions int, mut t Termios) int {
eprintln('tcsetattr, fd: ${fd}, optional_actions: ${optional_actions}, t: ${t}') eprintln('tcsetattr, fd: ${fd}, optional_actions: ${optional_actions}, t: ${t}')
return 0 return 0
} }
// ioctl is an unsafe wrapper around C.ioctl and keeps its semantic // ioctl is an unsafe wrapper around C.ioctl and keeps its semantic.
// It is only implemented for Unix like OSes // It is only implemented for Unix like OSes
pub fn ioctl(fd int, request u64, arg voidptr) int { pub fn ioctl(fd int, request u64, arg voidptr) int {
eprintln('ioctl, fd: ${fd}, request: ${request}, arg: ${arg}') eprintln('ioctl, fd: ${fd}, request: ${request}, arg: ${arg}')
@ -71,8 +69,7 @@ pub fn set_state(fd int, new_state Termios) int {
return 0 return 0
} }
// disable_echo disables echoing characters as they are typed // disable_echo disables echoing characters as they are typed, when that Termios state is later set with termios.set_state(fd,t).
// when that Termios state is later set with termios.set_state(fd,t)
pub fn (mut t Termios) disable_echo() { pub fn (mut t Termios) disable_echo() {
t.c_lflag &= invert(8) t.c_lflag &= invert(8)
} }

View file

@ -77,7 +77,7 @@ pub fn tcsetattr(fd int, optional_actions int, mut termios_p Termios) int {
} }
} }
// ioctl is an unsafe wrapper around C.ioctl and keeps its semantic // ioctl is an unsafe wrapper around C.ioctl and keeps its semantic.
@[inline] @[inline]
pub fn ioctl(fd int, request u64, arg voidptr) int { pub fn ioctl(fd int, request u64, arg voidptr) int {
unsafe { unsafe {
@ -91,8 +91,7 @@ pub fn set_state(fd int, new_state Termios) int {
return tcsetattr(0, C.TCSANOW, mut x) return tcsetattr(0, C.TCSANOW, mut x)
} }
// disable_echo disables echoing characters as they are typed, // disable_echo disables echoing characters as they are typed, when that Termios state is later set with termios.set_state(fd,t).
// when that Termios state is later set with termios.set_state(fd,t)
pub fn (mut t Termios) disable_echo() { pub fn (mut t Termios) disable_echo() {
t.c_lflag &= invert(C.ECHO) t.c_lflag &= invert(C.ECHO)
} }

View file

@ -91,8 +91,7 @@ pub fn set_state(fd int, new_state Termios) int {
return tcsetattr(0, C.TCSANOW, mut x) return tcsetattr(0, C.TCSANOW, mut x)
} }
// disable_echo disables echoing characters as they are typed, // disable_echo disables echoing characters as they are typed, when that Termios state is later set with termios.set_state(fd,t).
// when that Termios state is later set with termios.set_state(fd,t)
pub fn (mut t Termios) disable_echo() { pub fn (mut t Termios) disable_echo() {
t.c_lflag &= invert(C.ECHO) t.c_lflag &= invert(C.ECHO)
} }

View file

@ -93,8 +93,7 @@ pub fn set_state(fd int, new_state Termios) int {
return tcsetattr(0, C.TCSANOW, mut x) return tcsetattr(0, C.TCSANOW, mut x)
} }
// disable_echo disables echoing characters as they are typed, // disable_echo disables echoing characters as they are typed, when that Termios state is later set with termios.set_state(fd,t).
// when that Termios state is later set with termios.set_state(fd,t)
pub fn (mut t Termios) disable_echo() { pub fn (mut t Termios) disable_echo() {
t.c_lflag &= invert(C.ECHO) t.c_lflag &= invert(C.ECHO)
} }

View file

@ -91,8 +91,7 @@ pub fn set_state(fd int, new_state Termios) int {
return tcsetattr(0, C.TCSANOW, mut x) return tcsetattr(0, C.TCSANOW, mut x)
} }
// disable_echo disables echoing characters as they are typed, // disable_echo disables echoing characters as they are typed, when that Termios state is later set with termios.set_state(fd,t).
// when that Termios state is later set with termios.set_state(fd,t)
pub fn (mut t Termios) disable_echo() { pub fn (mut t Termios) disable_echo() {
t.c_lflag &= invert(C.ECHO) t.c_lflag &= invert(C.ECHO)
} }

View file

@ -91,8 +91,7 @@ pub fn set_state(fd int, new_state Termios) int {
return tcsetattr(0, C.TCSANOW, mut x) return tcsetattr(0, C.TCSANOW, mut x)
} }
// disable_echo disables echoing characters as they are typed, // disable_echo disables echoing characters as they are typed, when that Termios state is later set with termios.set_state(fd,t).
// when that Termios state is later set with termios.set_state(fd,t)
pub fn (mut t Termios) disable_echo() { pub fn (mut t Termios) disable_echo() {
t.c_lflag &= invert(C.ECHO) t.c_lflag &= invert(C.ECHO)
} }

View file

@ -93,8 +93,7 @@ pub fn set_state(fd int, new_state Termios) int {
return tcsetattr(0, C.TCSANOW, mut x) return tcsetattr(0, C.TCSANOW, mut x)
} }
// disable_echo disables echoing characters as they are typed, // disable_echo disables echoing characters as they are typed, when that Termios state is later set with termios.set_state(fd,t).
// when that Termios state is later set with termios.set_state(fd,t)
pub fn (mut t Termios) disable_echo() { pub fn (mut t Termios) disable_echo() {
t.c_lflag &= invert(C.ECHO) t.c_lflag &= invert(C.ECHO)
} }

View file

@ -87,8 +87,7 @@ pub fn set_state(fd int, new_state Termios) int {
return tcsetattr(0, C.TCSANOW, mut x) return tcsetattr(0, C.TCSANOW, mut x)
} }
// disable_echo disables echoing characters as they are typed, // disable_echo disables echoing characters as they are typed, when that Termios state is later set with termios.set_state(fd,t).
// when that Termios state is later set with termios.set_state(fd,t)
pub fn (mut t Termios) disable_echo() { pub fn (mut t Termios) disable_echo() {
t.c_lflag &= invert(C.ECHO) t.c_lflag &= invert(C.ECHO)
} }

View file

@ -12,16 +12,14 @@ type TcFlag = int
type Speed = int type Speed = int
type Cc = u8 type Cc = u8
// flag provides a termios flag of the correct size // flag provides a termios flag of the correct size for the underlying C.termios structure.
// for the underlying C.termios structure // It is only implemented for Unix like OSes.
// It is only implemented for Unix like OSes
pub fn flag(value int) TcFlag { pub fn flag(value int) TcFlag {
return int(value) return int(value)
} }
// invert is a platform dependant way to bitwise NOT (~) TcFlag // invert is a platform dependant way to bitwise NOT (~) TcFlag, as its length varies across platforms.
// as its length varies across platforms // It is only implemented for Unix like OSes.
// It is only implemented for Unix like OSes
pub fn invert(value TcFlag) TcFlag { pub fn invert(value TcFlag) TcFlag {
return ~int(value) return ~int(value)
} }
@ -38,20 +36,20 @@ pub mut:
c_ospeed Speed c_ospeed Speed
} }
// tcgetattr is an unsafe wrapper around C.termios and keeps its semantic // tcgetattr is an unsafe wrapper around C.termios and keeps its semantic.
// It is only implemented for Unix like OSes // It is only implemented for Unix like OSes.
pub fn tcgetattr(fd int, mut termios_p Termios) int { pub fn tcgetattr(fd int, mut termios_p Termios) int {
return -1 return -1
} }
// tcsetattr is an unsafe wrapper around C.termios and keeps its semantic // tcsetattr is an unsafe wrapper around C.termios and keeps its semantic.
// It is only implemented for Unix like OSes // It is only implemented for Unix like OSes.
pub fn tcsetattr(fd int, optional_actions int, mut termios_p Termios) int { pub fn tcsetattr(fd int, optional_actions int, mut termios_p Termios) int {
return -1 return -1
} }
// ioctl is an unsafe wrapper around C.ioctl and keeps its semantic // ioctl is an unsafe wrapper around C.ioctl and keeps its semantic.
// It is only implemented for Unix like OSes // It is only implemented for Unix like OSes.
@[inline] @[inline]
pub fn ioctl(fd int, request u64, arg voidptr) int { pub fn ioctl(fd int, request u64, arg voidptr) int {
return -1 return -1
@ -62,7 +60,6 @@ pub fn set_state(fd int, new_state Termios) int {
return -1 return -1
} }
// disable_echo disables echoing characters as they are typed, // disable_echo disables echoing characters as they are typed, when that Termios state is later set with termios.set_state(fd,t).
// when that Termios state is later set with termios.set_state(fd,t)
pub fn (mut t Termios) disable_echo() { pub fn (mut t Termios) disable_echo() {
} }

View file

@ -1,6 +1,6 @@
module term module term
// utf8_getchar returns an utf8 rune from standard input // utf8_getchar returns an utf8 rune from standard input.
pub fn utf8_getchar() ?rune { pub fn utf8_getchar() ?rune {
c := input_character() c := input_character()
if c == -1 { if c == -1 {
@ -30,7 +30,7 @@ pub fn utf8_getchar() ?rune {
} }
} }
// utf8_len calculates the length of a utf8 rune to read, according to its first byte // utf8_len calculates the length of a utf8 rune to read, according to its first byte.
pub fn utf8_len(c u8) int { pub fn utf8_len(c u8) int {
mut b := 0 mut b := 0
mut x := c mut x := c

View file

@ -4,8 +4,7 @@ import json
import orm import orm
import time import time
// DBStoreSessions is the table that is created in your database and represents // DBStoreSessions is the table that is created in your database and represents a session data record.
// a session data record
pub struct DBStoreSessions { pub struct DBStoreSessions {
pub mut: pub mut:
session_id string @[primary] session_id string @[primary]
@ -13,14 +12,14 @@ pub mut:
data string data string
} }
// DBStore stores sessions in a database // DBStore stores sessions in a database.
@[noinit] @[noinit]
pub struct DBStore[T] { pub struct DBStore[T] {
pub mut: pub mut:
db orm.Connection @[required] db orm.Connection @[required]
} }
// create a new Database store with a connection to a database // create a new Database store with a connection to a database.
pub fn DBStore.create[T](db orm.Connection) !DBStore[T] { pub fn DBStore.create[T](db orm.Connection) !DBStore[T] {
sql db { sql db {
create table DBStoreSessions create table DBStoreSessions
@ -31,7 +30,7 @@ pub fn DBStore.create[T](db orm.Connection) !DBStore[T] {
} }
} }
// all gets the data from all sessions // all gets the data from all sessions.
pub fn (mut store DBStore[T]) all() ![]T { pub fn (mut store DBStore[T]) all() ![]T {
rows := sql store.db { rows := sql store.db {
select from DBStoreSessions select from DBStoreSessions
@ -62,21 +61,21 @@ pub fn (mut store DBStore[T]) get(sid string, max_age time.Duration) !T {
} }
} }
// destroy data for session id `sid` // destroy data for session id `sid`.
pub fn (mut store DBStore[T]) destroy(sid string) ! { pub fn (mut store DBStore[T]) destroy(sid string) ! {
sql store.db { sql store.db {
delete from DBStoreSessions where session_id == sid delete from DBStoreSessions where session_id == sid
}! }!
} }
// clear all sessions // clear all sessions.
pub fn (mut store DBStore[T]) clear() ! { pub fn (mut store DBStore[T]) clear() ! {
sql store.db { sql store.db {
delete from DBStoreSessions where session_id != '' delete from DBStoreSessions where session_id != ''
}! }!
} }
// set session data for session id `sid` // set session data for session id `sid`.
pub fn (mut store DBStore[T]) set(sid string, val T) ! { pub fn (mut store DBStore[T]) set(sid string, val T) ! {
count := sql store.db { count := sql store.db {
select count from DBStoreSessions where session_id == sid select count from DBStoreSessions where session_id == sid

View file

@ -14,7 +14,7 @@ mut:
data map[string]MemoryStoreSessions[T] data map[string]MemoryStoreSessions[T]
} }
// get data from all sessions // get data from all sessions.
pub fn (mut store MemoryStore[T]) all() ![]T { pub fn (mut store MemoryStore[T]) all() ![]T {
return store.data.values().map(it.data) return store.data.values().map(it.data)
} }
@ -35,17 +35,17 @@ pub fn (mut store MemoryStore[T]) get(sid string, max_age time.Duration) !T {
} }
} }
// destroy data for session id `sid` // destroy data for session id `sid`.
pub fn (mut store MemoryStore[T]) destroy(sid string) ! { pub fn (mut store MemoryStore[T]) destroy(sid string) ! {
store.data.delete(sid) store.data.delete(sid)
} }
// clear all sessions // clear all sessions.
pub fn (mut store MemoryStore[T]) clear() ! { pub fn (mut store MemoryStore[T]) clear() ! {
store.data.clear() store.data.clear()
} }
// set session data for session id `sid` // set session data for session id `sid`.
pub fn (mut store MemoryStore[T]) set(sid string, val T) ! { pub fn (mut store MemoryStore[T]) set(sid string, val T) ! {
if sid in store.data { if sid in store.data {
store.data[sid].data = val store.data[sid].data = val

View file

@ -20,8 +20,8 @@ pub fn new_session_id(secret []u8) (string, string) {
return sid, '${sid}.${base64.url_encode(hashed)}' return sid, '${sid}.${base64.url_encode(hashed)}'
} }
// verify_session_id verifies the signed session id with `secret`. This function returns // verify_session_id verifies the signed session id with `secret`.
// the session id and if the session id is valid // This function returns the session id and if the session id is valid.
pub fn verify_session_id(raw_sid string, secret []u8) (string, bool) { pub fn verify_session_id(raw_sid string, secret []u8) (string, bool) {
parts := raw_sid.split('.') parts := raw_sid.split('.')
if parts.len != 2 { if parts.len != 2 {
@ -36,8 +36,8 @@ pub fn verify_session_id(raw_sid string, secret []u8) (string, bool) {
return sid, hmac.equal(actual_hmac, new_hmac) return sid, hmac.equal(actual_hmac, new_hmac)
} }
// CurrentSession contains the session data during a request. If you use x.vweb you // CurrentSession contains the session data during a request.
// could embed it on your Context struct to have easy access to the session id and data. // If you use x.vweb you could embed it on your Context struct to have easy access to the session id and data.
// Example: // Example:
// ```v // ```v
// pub struct Context { // pub struct Context {
@ -51,8 +51,7 @@ pub mut:
session_data ?T session_data ?T
} }
// CookieOptions contains the default settings for the cookie created in // CookieOptions contains the default settings for the cookie created in the `Sessions` struct.
// the `Sessions` struct.
pub struct CookieOptions { pub struct CookieOptions {
pub: pub:
cookie_name string = 'sid' cookie_name string = 'sid'
@ -87,7 +86,7 @@ pub mut:
store Store[T] @[required] store Store[T] @[required]
} }
// set_session_id generates a new session id and set a Set-Cookie header on the response // set_session_id generates a new session id and set a Set-Cookie header on the response.
pub fn (mut s Sessions[T]) set_session_id[X](mut ctx X) string { pub fn (mut s Sessions[T]) set_session_id[X](mut ctx X) string {
sid, signed := new_session_id(s.secret) sid, signed := new_session_id(s.secret)
ctx.CurrentSession.session_id = sid ctx.CurrentSession.session_id = sid
@ -110,20 +109,20 @@ pub fn (mut s Sessions[T]) set_session_id[X](mut ctx X) string {
return sid return sid
} }
// validate_session validates the current session, returns the session id and the validation status // validate_session validates the current session, returns the session id and the validation status.
pub fn (mut s Sessions[T]) validate_session[X](ctx X) (string, bool) { pub fn (mut s Sessions[T]) validate_session[X](ctx X) (string, bool) {
cookie := ctx.get_cookie(s.cookie_options.cookie_name) or { return '', false } cookie := ctx.get_cookie(s.cookie_options.cookie_name) or { return '', false }
return verify_session_id(cookie, s.secret) return verify_session_id(cookie, s.secret)
} }
// get the data associated with the current session, if it exists // get the data associated with the current session, if it exists.
pub fn (mut s Sessions[T]) get[X](ctx X) !T { pub fn (mut s Sessions[T]) get[X](ctx X) !T {
sid := s.get_session_id(ctx) or { return error('cannot find session id') } sid := s.get_session_id(ctx) or { return error('cannot find session id') }
return s.store.get(sid, s.max_age)! return s.store.get(sid, s.max_age)!
} }
// destroy the data for the current session // destroy the data for the current session.
pub fn (mut s Sessions[T]) destroy[X](mut ctx X) ! { pub fn (mut s Sessions[T]) destroy[X](mut ctx X) ! {
if sid := s.get_session_id(ctx) { if sid := s.get_session_id(ctx) {
s.store.destroy(sid)! s.store.destroy(sid)!
@ -131,8 +130,7 @@ pub fn (mut s Sessions[T]) destroy[X](mut ctx X) ! {
} }
} }
// logout destroys the data for the current session and removes // logout destroys the data for the current session and removes the session id Cookie.
// the session id Cookie
pub fn (mut s Sessions[T]) logout[X](mut ctx X) ! { pub fn (mut s Sessions[T]) logout[X](mut ctx X) ! {
s.destroy(mut ctx)! s.destroy(mut ctx)!
ctx.set_cookie(http.Cookie{ ctx.set_cookie(http.Cookie{
@ -142,7 +140,7 @@ pub fn (mut s Sessions[T]) logout[X](mut ctx X) ! {
}) })
} }
// save `data` for the current session // save `data` for the current session.
pub fn (mut s Sessions[T]) save[X](mut ctx X, data T) ! { pub fn (mut s Sessions[T]) save[X](mut ctx X, data T) ! {
if sid := s.get_session_id(ctx) { if sid := s.get_session_id(ctx) {
s.store.set(sid, data)! s.store.set(sid, data)!
@ -171,7 +169,7 @@ pub fn (mut s Sessions[T]) resave[X](mut ctx X, data T) ! {
s.save(mut ctx, data) s.save(mut ctx, data)
} }
// get_session_id retrieves the current session id, if it is set // get_session_id retrieves the current session id, if it is set.
pub fn (s &Sessions[T]) get_session_id[X](ctx X) ?string { pub fn (s &Sessions[T]) get_session_id[X](ctx X) ?string {
// first check session id from `ctx` // first check session id from `ctx`
sid_from_ctx := ctx.CurrentSession.session_id sid_from_ctx := ctx.CurrentSession.session_id

View file

@ -12,10 +12,10 @@ mut:
set(sid string, val T) ! set(sid string, val T) !
} }
// get data from all sessions, optional to implement // get data from all sessions, optional to implement.
pub fn (mut s Store) all[T]() ![]T { pub fn (mut s Store) all[T]() ![]T {
return []T{} return []T{}
} }
// clear all session data, optional to implement // clear all session data, optional to implement.
pub fn (mut s Store) clear[T]() ! {} pub fn (mut s Store) clear[T]() ! {}

View file

@ -38,7 +38,6 @@ const message_signature_info = '[Dynamic Template Manager] Info :'
const message_signature_error = '[Dynamic Template Manager] Error :' const message_signature_error = '[Dynamic Template Manager] Error :'
const message_signature_warn = '[Dynamic Template Manager] Warning :' const message_signature_warn = '[Dynamic Template Manager] Warning :'
// CacheStorageMode
pub enum CacheStorageMode { pub enum CacheStorageMode {
memory memory
disk disk
@ -57,7 +56,6 @@ enum TemplateType {
text text
} }
// DynamicTemplateManager
@[heap] @[heap]
pub struct DynamicTemplateManager { pub struct DynamicTemplateManager {
mut: mut:
@ -180,14 +178,12 @@ pub:
// A cache directory can be created by the user for storage. If it is not defined or encounters issues such as permission problems, // A cache directory can be created by the user for storage. If it is not defined or encounters issues such as permission problems,
// the DTM will attempt to create it in the OS's temporary area. If this proves impossible, the cache system will be deactivated and the user will be informed if cache system was required. // the DTM will attempt to create it in the OS's temporary area. If this proves impossible, the cache system will be deactivated and the user will be informed if cache system was required.
// Initialisation params are : // Initialisation params are :
//
// - def_cache_path 'type string' User can define the path of cache folder. // - def_cache_path 'type string' User can define the path of cache folder.
// - max_size_data_in_mem 'type int' Maximum size of data allowed in memory for caching. The value must be specified in kilobytes. ( Default is: 500KB / Limit max is : 500KB) // - max_size_data_in_mem 'type int' Maximum size of data allowed in memory for caching. The value must be specified in kilobytes. ( Default is: 500KB / Limit max is : 500KB)
// - compress_html: 'type bool' Light compress of the HTML output. ( default is true ) // - compress_html: 'type bool' Light compress of the HTML output. ( default is true )
// - active_cache_server: 'type bool' Activate or not the template cache system. ( default is true ) // - active_cache_server: 'type bool' Activate or not the template cache system. ( default is true )
// - test_cache_dir: 'type string' Used only for DTM internal test file, parameter is ignored otherwise. // - test_cache_dir: 'type string' Used only for DTM internal test file, parameter is ignored otherwise.
// - test_template_dir: 'type string' Used only for DTM internal test file, parameter is ignored otherwise. // - test_template_dir: 'type string' Used only for DTM internal test file, parameter is ignored otherwise.
//
pub fn initialize(dtm_init_params DynamicTemplateManagerInitialisationParams) &DynamicTemplateManager { pub fn initialize(dtm_init_params DynamicTemplateManagerInitialisationParams) &DynamicTemplateManager {
mut dir_path := '' mut dir_path := ''
mut dir_html_path := '' mut dir_html_path := ''
@ -354,9 +350,10 @@ pub fn (mut tm DynamicTemplateManager) expand(tmpl_path string, tmpl_var Templat
} }
} }
// stop_cache_handler signals the termination of the cache handler by setting 'close_cache_handler' to true and sending a signal through the channel // stop_cache_handler signals the termination of the cache handler.
// which will trigger a cascading effect to close the cache handler thread as well as the DTM clock thread. // It does so by setting 'close_cache_handler' to true, and sending a signal
// // through the channel which will trigger a cascading effect to close the cache
// handler thread as well as the DTM clock thread.
pub fn (mut tm DynamicTemplateManager) stop_cache_handler() { pub fn (mut tm DynamicTemplateManager) stop_cache_handler() {
if tm.active_cache_server { if tm.active_cache_server {
tm.active_cache_server = false tm.active_cache_server = false
@ -368,19 +365,15 @@ pub fn (mut tm DynamicTemplateManager) stop_cache_handler() {
} }
} }
// fn check_and_clear_cache_files() // check_and_clear_cache_files is used exclusively during the initialization of the DTM (Dynamic Template Manager).
//
// Used exclusively during the initialization of the DTM (Dynamic Template Manager).
// Its primary purpose is to ensure a clean starting environment by clearing all files // Its primary purpose is to ensure a clean starting environment by clearing all files
// within the designated cache directory. It iterates through the directory, listing all files, // within the designated cache directory. It iterates through the directory, listing all files,
// and systematically removes each file found, ensuring that no residual cache data persists // and systematically removes each file found, ensuring that no residual cache data persists
// from previous executions. Additionally, this function also tests the read and write permissions // from previous executions. Additionally, this function also tests the read and write permissions
// of the cache directory to ensure that the application has the necessary access to properly manage the cache files. // of the cache directory to ensure that the application has the necessary access to properly manage the cache files.
//
// WARNING: When setting the directory for caching files and for testing purposes, // WARNING: When setting the directory for caching files and for testing purposes,
// this function will delete all "*.cache" or "*.tmp" files inside the cache directory in the project root's. Ensure that // this function will delete all "*.cache" or "*.tmp" files inside the cache directory in the project root's. Ensure that
// directory used for the cache does not contain any important files. // directory used for the cache does not contain any important files.
//
fn check_and_clear_cache_files(c_folder string) ! { fn check_and_clear_cache_files(c_folder string) ! {
// println('${message_signature} WARNING! DTM needs to perform some file tests in the cache directory. This operation will erase all "*.cache" or "*.tmp" files content in the folder : "${tm.template_cache_folder}"') // println('${message_signature} WARNING! DTM needs to perform some file tests in the cache directory. This operation will erase all "*.cache" or "*.tmp" files content in the folder : "${tm.template_cache_folder}"')
// println('Do you want to continue the operation? (yes/no)') // println('Do you want to continue the operation? (yes/no)')
@ -416,14 +409,11 @@ fn check_and_clear_cache_files(c_folder string) ! {
// } // }
} }
// fn (mut DynamicTemplateManager) check_tmpl_and_placeholders_size(string, &map[string]DtmMultiTypeMap) return !(string, string, string, TemplateType) // check_tmpl_and_placeholders_size is used exclusively in the 'expand' function, this check verifies if the template file exists.
//
// Used exclusively in the 'expand' function, this check verifies if the template file exists.
// It also ensures the file extension is correct ( like HTML or TXT ) and controls the size of placeholder keys and values in the provided map, // It also ensures the file extension is correct ( like HTML or TXT ) and controls the size of placeholder keys and values in the provided map,
// offering a basic validation and security measure against excessively long and potentially harmful inputs. // offering a basic validation and security measure against excessively long and potentially harmful inputs.
// Size limits are defined by the 'max_placeholders_key_size' and 'max_placeholders_value_size' constants. // Size limits are defined by the 'max_placeholders_key_size' and 'max_placeholders_value_size' constants.
// Monitor dynamic content for updates by generating a checksum that is compared against the cached version to verify any changes. // Monitor dynamic content for updates by generating a checksum that is compared against the cached version to verify any changes.
//
fn (mut tm DynamicTemplateManager) check_tmpl_and_placeholders_size(f_path string, tmpl_var &map[string]DtmMultiTypeMap) !(string, string, string, TemplateType) { fn (mut tm DynamicTemplateManager) check_tmpl_and_placeholders_size(f_path string, tmpl_var &map[string]DtmMultiTypeMap) !(string, string, string, TemplateType) {
mut html_file := '' mut html_file := ''
mut file_name := '' mut file_name := ''
@ -510,10 +500,8 @@ fn (mut tm DynamicTemplateManager) check_tmpl_and_placeholders_size(f_path strin
return html_file, file_name, res_checksum_content, define_file_type return html_file, file_name, res_checksum_content, define_file_type
} }
// fn (mut DynamicTemplateManager) create_template_cache_and_display(CacheRequest, i64, i64, string, string, i64, &map[string]DtmMultiTypeMap, string, TemplateType) return string // create_template_cache_and_display is exclusively invoked from `expand`.
// // It generates the template rendering and relaying information
// Exclusively invoked from `expand`.
// It role is generate the template rendering and relaying information
// to the cache manager for either the creation or updating of the template cache. // to the cache manager for either the creation or updating of the template cache.
// It begin to starts by ensuring that the cache delay expiration is correctly set by user. // It begin to starts by ensuring that the cache delay expiration is correctly set by user.
// It then parses the template file, replacing placeholders with actual dynamics/statics values. // It then parses the template file, replacing placeholders with actual dynamics/statics values.
@ -521,7 +509,6 @@ fn (mut tm DynamicTemplateManager) check_tmpl_and_placeholders_size(f_path strin
// the function constructs a `TemplateCache` request with all the necessary details. // the function constructs a `TemplateCache` request with all the necessary details.
// This request is then sent to the cache handler channel, signaling either the need for a new cache or an update to an existing one. // This request is then sent to the cache handler channel, signaling either the need for a new cache or an update to an existing one.
// The function returns the rendered immediately, without waiting for the cache to be created or updated. // The function returns the rendered immediately, without waiting for the cache to be created or updated.
//
fn (mut tm DynamicTemplateManager) create_template_cache_and_display(tcs CacheRequest, last_template_mod i64, fn (mut tm DynamicTemplateManager) create_template_cache_and_display(tcs CacheRequest, last_template_mod i64,
unique_time i64, file_path string, tmpl_name string, cache_delay_expiration i64, placeholders &map[string]DtmMultiTypeMap, unique_time i64, file_path string, tmpl_name string, cache_delay_expiration i64, placeholders &map[string]DtmMultiTypeMap,
current_content_checksum string, tmpl_type TemplateType) string { current_content_checksum string, tmpl_type TemplateType) string {
@ -567,13 +554,10 @@ fn (mut tm DynamicTemplateManager) create_template_cache_and_display(tcs CacheRe
return html return html
} }
// fn (DynamicTemplateManager) create_temp_cache(&string, string, i64) return (bool, string) // create_temp_cache is responsible for creating a temporary cache file, which is subsequently used exclusively by the cache manager.
//
// This function is responsible for creating a temporary cache file, which is subsequently used exclusively by the cache manager.
// It generates a temporary file name using a checksum based on the timestamp and the file path. // It generates a temporary file name using a checksum based on the timestamp and the file path.
// The content is then written to this file, located in the designated cache folder. // The content is then written to this file, located in the designated cache folder.
// If the operation is successful, a boolean is returned to allow for the sending of a create or modify request to the cache manager. // If the operation is successful, a boolean is returned to allow for the sending of a create or modify request to the cache manager.
//
fn (tm DynamicTemplateManager) create_temp_cache(html &string, f_path string, ts i64) (bool, string) { fn (tm DynamicTemplateManager) create_temp_cache(html &string, f_path string, ts i64) (bool, string) {
// Extracts the base file name with extension from the given file path. // Extracts the base file name with extension from the given file path.
file_name_with_ext := os.base(f_path) file_name_with_ext := os.base(f_path)
@ -602,10 +586,7 @@ fn (tm DynamicTemplateManager) create_temp_cache(html &string, f_path string, ts
return true, tmp_name return true, tmp_name
} }
// fn (mut DynamicTemplateManager) get_cache(string, string, &map[string]DtmMultiTypeMap) return string // get_cache is exclusively invoked from `expand', retrieves the rendered HTML from the cache.
//
// Exclusively invoked from `expand', retrieves the rendered HTML from the cache.
//
fn (mut tm DynamicTemplateManager) get_cache(name string, path string, placeholders &map[string]DtmMultiTypeMap) string { fn (mut tm DynamicTemplateManager) get_cache(name string, path string, placeholders &map[string]DtmMultiTypeMap) string {
mut html := '' mut html := ''
// Lock the cache database for writing. // Lock the cache database for writing.
@ -636,11 +617,8 @@ fn (mut tm DynamicTemplateManager) get_cache(name string, path string, placehold
return html return html
} }
// fn (mut DynamicTemplateManager) return_cache_info_isexistent(string) return (bool, int, string, i64, i64, i64, string) // return_cache_info_isexistent is exclusively used in 'expand' to determine whether a cache exists for the provided HTML template.
//
// Exclusively used in 'expand' to determine whether a cache exists for the provided HTML template.
// If a cache exists, it returns the necessary information for its transformation. If not, it indicates the need to create a new cache. // If a cache exists, it returns the necessary information for its transformation. If not, it indicates the need to create a new cache.
//
fn (mut tm DynamicTemplateManager) return_cache_info_isexistent(tmpl_path string) (bool, int, string, i64, i64, i64, string) { fn (mut tm DynamicTemplateManager) return_cache_info_isexistent(tmpl_path string) (bool, int, string, i64, i64, i64, string) {
// Lock the cache database for writing. // Lock the cache database for writing.
rlock tm.template_caches { rlock tm.template_caches {
@ -687,13 +665,9 @@ fn (mut tm DynamicTemplateManager) return_cache_info_isexistent(tmpl_path string
return false, 0, '', 0, 0, 0, '' return false, 0, '', 0, 0, 0, ''
} }
// fn (mut DynamicTemplateManager) remaining_template_request(bool, int) // remaining_template_request manages the counter in 'nbr_of_remaining_template_request', which tracks the number of requests that have started or finished for a specific cache.
//
// This function manages the counter in 'nbr_of_remaining_template_request', which tracks the number of requests that have started or finished for a specific cache.
// It updates this information accordingly.
// Moreover, this function sends a cache deletion callback request when the cache manager had previously been instructed to delete the cache but was unable to do because, // Moreover, this function sends a cache deletion callback request when the cache manager had previously been instructed to delete the cache but was unable to do because,
// it was still in use. // it was still in use.
//
fn (mut tm DynamicTemplateManager) remaining_template_request(b bool, v int) { fn (mut tm DynamicTemplateManager) remaining_template_request(b bool, v int) {
// Lock the remaining template request process for reading and writing. // Lock the remaining template request process for reading and writing.
lock tm.nbr_of_remaining_template_request { lock tm.nbr_of_remaining_template_request {

View file

@ -16,8 +16,7 @@ module ttf
import encoding.utf8 import encoding.utf8
import math import math
// BitMap represents a bitmap image of text rendered with the font supplied via // BitMap represents a bitmap image of text rendered with the font supplied via the `tf` field.
// the `tf` field.
pub struct BitMap { pub struct BitMap {
pub mut: pub mut:
tf &TTF_File = unsafe { nil } tf &TTF_File = unsafe { nil }
@ -72,13 +71,13 @@ pub fn (bmp &BitMap) trf_ch(p &Point) (int, int) {
p.x * bmp.ch_matrix[1] + p.y * bmp.ch_matrix[4] + bmp.ch_matrix[7]) p.x * bmp.ch_matrix[1] + p.y * bmp.ch_matrix[4] + bmp.ch_matrix[7])
} }
// set_pos sets the draw position in the buffer // set_pos sets the draw position in the buffer.
pub fn (mut bmp BitMap) set_pos(x f32, y f32) { pub fn (mut bmp BitMap) set_pos(x f32, y f32) {
bmp.tr_matrix[6] = x bmp.tr_matrix[6] = x
bmp.tr_matrix[7] = y bmp.tr_matrix[7] = y
} }
// set_rotation sets the rotation angle in radians `a` // set_rotation sets the rotation angle in radians `a`.
pub fn (mut bmp BitMap) set_rotation(a f32) { pub fn (mut bmp BitMap) set_rotation(a f32) {
bmp.tr_matrix[0] = f32(math.cos(a)) // 1 bmp.tr_matrix[0] = f32(math.cos(a)) // 1
bmp.tr_matrix[1] = f32(-math.sin(a)) // 0 bmp.tr_matrix[1] = f32(-math.sin(a)) // 0
@ -103,7 +102,7 @@ pub fn (mut bmp BitMap) init_filler() {
// dprintln("Init filler: ${bmp.filler.len} rows") // dprintln("Init filler: ${bmp.filler.len} rows")
} }
// clear_filler clears the internal `filler` buffer // clear_filler clears the internal `filler` buffer.
pub fn (mut bmp BitMap) clear_filler() { pub fn (mut bmp BitMap) clear_filler() {
for i in 0 .. bmp.height { for i in 0 .. bmp.height {
bmp.filler[i].clear() bmp.filler[i].clear()
@ -220,7 +219,7 @@ pub fn (mut bmp BitMap) plot(x int, y int, c u32) bool {
* smooth draw functions * smooth draw functions
* *
******************************************************************************/ ******************************************************************************/
// aline draws an aliased line on the bitmap // aline draws an aliased line on the bitmap.
pub fn (mut bmp BitMap) aline(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) { pub fn (mut bmp BitMap) aline(in_x0 int, in_y0 int, in_x1 int, in_y1 int, c u32) {
// mut c1 := c // mut c1 := c
mut x0 := f32(in_x0) mut x0 := f32(in_x0)
@ -642,8 +641,8 @@ fn (mut bmp BitMap) draw_notdef_glyph(in_x int, in_w int) {
bmp.line(int(x - in_w), int(y), int(x), int(y - y_h), bmp.color) bmp.line(int(x - in_w), int(y), int(x), int(y - y_h), bmp.color)
} }
// draw_text plots the pixels of the text `in_string` to the internal buffer and // draw_text plots the pixels of the text `in_string` to the internal buffer.
// returns the text bounding box. // It returns the text bounding box.
pub fn (mut bmp BitMap) draw_text(in_string string) (int, int) { pub fn (mut bmp BitMap) draw_text(in_string string) (int, int) {
mut w := 0 mut w := 0
@ -719,8 +718,8 @@ pub fn (mut bmp BitMap) draw_text(in_string string) (int, int) {
return w, int(math.abs(int(bmp.tf.y_max - bmp.tf.y_min)) * bmp.scale) return w, int(math.abs(int(bmp.tf.y_max - bmp.tf.y_min)) * bmp.scale)
} }
// draw_glyph plots the pixels of the glyph at `index` to the internal buffer and // draw_glyph plots the pixels of the glyph at `index` to the internal buffer.
// returns the `x_max` and `x_min` values. // It returns the `x_max` and `x_min` values.
pub fn (mut bmp BitMap) draw_glyph(index u16) (int, int) { pub fn (mut bmp BitMap) draw_glyph(index u16) (int, int) {
glyph := bmp.tf.read_glyph(index) glyph := bmp.tf.read_glyph(index)

View file

@ -17,8 +17,7 @@ import gg
import sokol.sgl import sokol.sgl
import sokol.gfx import sokol.gfx
// TTF_render_Sokol is a structure containing data for rendering a TTF font // TTF_render_Sokol is a structure containing data for rendering a TTF font as a sokol texture.
// as a sokol texture
pub struct TTF_render_Sokol { pub struct TTF_render_Sokol {
pub mut: pub mut:
bmp &BitMap = unsafe { nil } // Base bitmap render bmp &BitMap = unsafe { nil } // Base bitmap render

View file

@ -38,16 +38,10 @@ mut:
arr []int arr []int
} }
/******************************************************************************
*
* TTF_File structs
*
******************************************************************************/
// TTF_File represents the data contents of a complete `*.ttf` file. // TTF_File represents the data contents of a complete `*.ttf` file.
// The struct is usually initialized by reading raw TTF data into the `buf` member field // The struct is usually initialized by reading raw TTF data into the `buf` member field
// for example by doing: `ttf_font.buf = os.read_bytes("arial.ttf") or { panic(err) }`, // for example by doing: `ttf_font.buf = os.read_bytes("arial.ttf") or { panic(err) }`,
// and then run the `init/0` method, for example: `ttf_font.init()` // and then run the `init/0` method, for example: `ttf_font.init()`
pub struct TTF_File { pub struct TTF_File {
pub mut: pub mut:
buf []u8 buf []u8
@ -118,12 +112,7 @@ pub fn (mut tf TTF_File) init() {
dprintln('advance_width_max: ${tf.advance_width_max}') dprintln('advance_width_max: ${tf.advance_width_max}')
} }
/****************************************************************************** // Point represents a 2D point.
*
* TTF_File Glyph Structs
*
******************************************************************************/
// Point represents a 2D point
pub struct Point { pub struct Point {
pub mut: pub mut:
x int x int
@ -156,13 +145,9 @@ pub mut:
components []Component components []Component
} }
/****************************************************************************** // TTF_File metrics and glyph
*
* TTF_File metrics and glyph // get_horizontal_metrics returns the horizontal metrics `advance_width` and `left_side_bearing` for the glyph at index `glyph_index`.
*
******************************************************************************/
// get_horizontal_metrics returns the horizontal metrics `advance_width` and `left_side_bearing`
// for the glyph at index `glyph_index`.
pub fn (mut tf TTF_File) get_horizontal_metrics(glyph_index u16) (int, int) { pub fn (mut tf TTF_File) get_horizontal_metrics(glyph_index u16) (int, int) {
assert 'hmtx' in tf.tables assert 'hmtx' in tf.tables
old_pos := tf.pos old_pos := tf.pos