ParamsParser Module: Flexible Parameter Handling in V
The ParamsParser module in V provides a robust and intuitive way to parse and manage parameters from various string inputs, such as command-line arguments, configuration strings, or key-value data. It simplifies the extraction and type conversion of values, making it ideal for applications requiring flexible and dynamic parameter processing.
Key Features
- Flexible Parsing: Supports key-value pairs, quoted values, and positional arguments.
- Automatic Type Conversion: Easily retrieve values as strings, integers, floats, booleans, and various list types.
- Error Handling: Integrates with V's error handling for reliable operations.
- Case-Insensitive Keys: Provides convenience by treating keys as case-insensitive.
- Merging Capabilities: Combine multiple parameter sets effortlessly.
Installation
import freeflowuniverse.herolib.data.paramsparser
Basic Usage
Creating Parameters
You can create a new Params object from a string or initialize an empty one:
// 1. Create from a parameter string
params_from_string := paramsparser.new("color:red size:'large item:apple' priority:1 enable:true")!
// 2. Create an empty Params object and add values later
mut empty_params := paramsparser.new_params()
empty_params.set("product", "laptop")
empty_params.set("price", "1200")
Parameter String Format
The parser understands several common parameter formats:
- Key-Value Pairs:
key:value(e.g.,name:John) - Quoted Values:
key:'value with spaces'orkey:"value with spaces"(essential for values containing spaces or special characters) - Positional Arguments:
arg1 arg2(values without an explicit key) - Comments:
// this is a comment(lines starting with//are ignored)
Example:
text := "user_name:'Alice Smith' age:28 active:true // user profile data"
parsed_params := paramsparser.new(text)!
// Accessing values
println(parsed_params.get("user_name")!) // Output: Alice Smith
println(parsed_params.get_int("age")!) // Output: 28
println(parsed_params.get_default_true("active")) // Output: true
Retrieving Values
The ParamsParser offers a variety of methods to retrieve values, including type-specific getters and options for default values.
Common Getters
// Get string value
name := parsed_params.get("user_name")! // Returns "Alice Smith"
// Get with a default value if key is not found
city := parsed_params.get_default("city", "Unknown")! // Returns "Unknown" if 'city' is not set
// Get as integer
age := parsed_params.get_int("age")! // Returns 28
// Get as float
temperature := parsed_params.get_float("temp")! // Converts "25.5" to 25.5
// Get as percentage (converts "75%" to 0.75)
completion := parsed_params.get_percentage("progress")!
Boolean Values
Boolean getters are flexible and interpret common truthy/falsy strings:
get_default_true(key string): Returnstrueif the value is empty, "1", "true", "y", or "yes". Otherwise,false.get_default_false(key string): Returnsfalseif the value is empty, "0", "false", "n", or "no". Otherwise,true.
is_enabled := parsed_params.get_default_true("enable_feature") // "enable_feature:yes" -> true
is_debug := parsed_params.get_default_false("debug_mode") // "debug_mode:0" -> false
List Values
The module provides comprehensive support for parsing and converting lists of various types. Lists can be defined using square brackets [] or comma-separated values.
// Example parameter string with lists
list_params := paramsparser.new("items:['apple', 'banana', 'orange'] ids:101,102,103 prices:[1.99, 2.50, 0.75]")!
// Get a list of strings
fruits := list_params.get_list("items")! // Returns ["apple", "banana", "orange"]
// Get a list of integers
item_ids := list_params.get_list_int("ids")! // Returns [101, 102, 103]
// Get a list of floats
product_prices := list_params.get_list_f64("prices")! // Returns [1.99, 2.50, 0.75]
// Get a list with a default value if the key is not found
categories := list_params.get_list_default("categories", ["misc"])!
// Name-fixed lists (normalizes each item, e.g., "My Category" -> "my_category")
clean_tags := list_params.get_list_namefix("tags")!
Supported List Types:
get_list():[]stringget_list_u8(),get_list_u16(),get_list_u32(),get_list_u64(): Unsigned integer listsget_list_i8(),get_list_i16(),get_list_int(),get_list_i64(): Signed integer listsget_list_f32(),get_list_f64(): Floating-point lists
Each list method also has a _default version (e.g., get_list_int_default) for providing fallback values.
Working with Positional Arguments
Arguments are values provided without a key.
// Parse text with positional arguments
arg_params := paramsparser.new("command_name --verbose file.txt")!
// Add a new argument
arg_params.set_arg("another_arg")
// Check if an argument exists
if arg_params.exists_arg("file.txt") {
println("File argument found!")
}
// Get all arguments
all_args := arg_params.get_args() // Returns ["command_name", "--verbose", "file.txt", "another_arg"]
Advanced Features
Case-Insensitive Keys
Keys are treated as case-insensitive for retrieval, promoting flexibility.
params := paramsparser.new_params()
params.set("FileName", "document.pdf")
value := params.get("filename")! // Successfully retrieves "document.pdf"
Converting to Map
Easily convert the parsed parameters into a standard V map.
params := paramsparser.new("key1:value1 key2:value2")!
map_representation := params.get_map()
println(map_representation["key1"]) // Output: value1
Merging Parameters
Combine two Params objects, with values from the merged object overriding existing keys.
mut params1 := paramsparser.new("color:red size:small")!
params2 := paramsparser.new("size:large material:wood")!
params1.merge(params2)!
// params1 now contains: color:red, size:large, material:wood
Deleting Parameters
Remove specific key-value pairs or positional arguments.
params := paramsparser.new("item:book quantity:5 arg1 arg2")!
params.delete("quantity") // Removes 'quantity:5'
params.delete_arg("arg1") // Removes 'arg1'
Error Handling
Most ParamsParser methods that retrieve or convert values return Result types, requiring explicit error handling using V's ! operator or or {} block.
// Using the '!' operator (panics on error)
required_value := params.get("mandatory_key")!
// Using 'or {}' for graceful error handling
optional_value := params.get("optional_key") or {
eprintln("Warning: 'optional_key' not found or invalid: ${err}")
"default_fallback_value"
}
Parameter Validation Rules
The parser adheres to the following rules for input strings:
- Keys: Must consist of alphanumeric characters, underscores (
_), dots (.), and forward slashes (/). - Values: Can contain any characters.
- Spaces in Values: Must be enclosed within single (
') or double (") quotes. - Lists: Supported with comma separation or square bracket notation.
Best Practices for Usage
- Always Handle Errors: Use
!oror {}to manage potential parsing or conversion failures. - Use Type-Specific Getters: Prefer
get_int(),get_float(), etc., when you know the expected data type for clarity and safety. - Provide Default Values: Utilize
_defaultmethods (e.g.,get_default,get_list_default) to ensure your application behaves predictably when parameters are missing. - Quote Values with Spaces: Always enclose values containing spaces or special characters in quotes to ensure correct parsing.
- Consistent Key Naming: While case-insensitive, using a consistent naming convention (e.g.,
snake_caseorcamelCase) for keys improves human readability and maintainability.