...
This commit is contained in:
13
README.md
13
README.md
@@ -7,17 +7,6 @@ Herolib is an opinionated library primarily used by ThreeFold to automate cloud
|
||||
|
||||
> [Complete Documentation](https://freeflowuniverse.github.io/herolib/)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Installation](#installation)
|
||||
- [For Users](#for-users)
|
||||
- [For Developers](#for-developers)
|
||||
- [Features](#features)
|
||||
- [Testing](#testing)
|
||||
- [Contributing](#contributing)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Additional Resources](#additional-resources)
|
||||
|
||||
## Installation
|
||||
|
||||
### For Users
|
||||
@@ -27,6 +16,8 @@ The Hero tool can be installed with a single command:
|
||||
```bash
|
||||
curl https://raw.githubusercontent.com/freeflowuniverse/herolib/refs/heads/development/install_hero.sh > /tmp/install_hero.sh
|
||||
bash /tmp/install_hero.sh
|
||||
#do not forget to do the following this makes sure vtest and vrun exists
|
||||
bash install_herolib.vsh
|
||||
```
|
||||
|
||||
Hero will be installed in:
|
||||
|
||||
141
aiprompts/herolib_advanced/advanced_paths.md
Normal file
141
aiprompts/herolib_advanced/advanced_paths.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# Pathlib Module: Advanced Listing and Filtering
|
||||
|
||||
The `pathlib` module provides powerful capabilities for listing and filtering files and directories, especially through its `list` method. This document explains how to leverage advanced features like regular expressions and various filtering options.
|
||||
|
||||
## Advanced File Listing with `path.list()`
|
||||
|
||||
The `path.list()` method allows you to retrieve a `PathList` object containing `Path` objects that match specified criteria.
|
||||
|
||||
### `ListArgs` Parameters
|
||||
|
||||
The `list` method accepts a `ListArgs` struct to control its behavior:
|
||||
|
||||
```v
|
||||
pub struct ListArgs {
|
||||
pub mut:
|
||||
regex []string // A slice of regular expressions to filter files.
|
||||
recursive bool = true // Whether to list files recursively (default true).
|
||||
ignoredefault bool = true // Whether to ignore files starting with . and _ (default true).
|
||||
include_links bool // Whether to include symbolic links in the list.
|
||||
dirs_only bool // Whether to include only directories in the list.
|
||||
files_only bool // Whether to include only files in the list.
|
||||
}
|
||||
```
|
||||
|
||||
### Usage Examples
|
||||
|
||||
Here are examples demonstrating how to use these advanced filtering options:
|
||||
|
||||
#### 1. Listing Files by Regex Pattern
|
||||
|
||||
You can use regular expressions to filter files based on their names or extensions. The `regex` parameter accepts a slice of strings, where each string is a regex pattern.
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
|
||||
// Get a directory path
|
||||
mut dir := pathlib.get('/some/directory')!
|
||||
|
||||
// List only Vlang files (ending with .v)
|
||||
mut vlang_files := dir.list(
|
||||
regex: [r'.*\.v$']
|
||||
)!
|
||||
|
||||
// List only image files (png, jpg, svg, jpeg)
|
||||
mut image_files := dir.list(
|
||||
regex: [r'.*\.png$', r'.*\.jpg$', r'.*\.svg$', r'.*\.jpeg$']
|
||||
)!
|
||||
|
||||
// List files containing "test" in their name (case-insensitive)
|
||||
mut test_files := dir.list(
|
||||
regex: [r'(?i).*test.*'] // (?i) makes the regex case-insensitive
|
||||
)!
|
||||
|
||||
for path_obj in vlang_files.paths {
|
||||
println(path_obj.path)
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. Controlling Recursion
|
||||
|
||||
By default, `list()` is recursive. You can disable recursion to list only items in the current directory.
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
|
||||
mut dir := pathlib.get('/some/directory')!
|
||||
|
||||
// List only top-level files and directories (non-recursive)
|
||||
mut top_level_items := dir.list(
|
||||
recursive: false
|
||||
)!
|
||||
|
||||
for path_obj in top_level_items.paths {
|
||||
println(path_obj.path)
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. Including or Excluding Hidden Files
|
||||
|
||||
The `ignoredefault` parameter controls whether files and directories starting with `.` or `_` are ignored.
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
|
||||
mut dir := pathlib.get('/some/directory')!
|
||||
|
||||
// List all files and directories, including hidden ones
|
||||
mut all_items := dir.list(
|
||||
ignoredefault: false
|
||||
)!
|
||||
|
||||
for path_obj in all_items.paths {
|
||||
println(path_obj.path)
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. Including Symbolic Links
|
||||
|
||||
By default, symbolic links are ignored when walking the directory structure. Set `include_links` to `true` to include them.
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
|
||||
mut dir := pathlib.get('/some/directory')!
|
||||
|
||||
// List files and directories, including symbolic links
|
||||
mut items_with_links := dir.list(
|
||||
include_links: true
|
||||
)!
|
||||
|
||||
for path_obj in items_with_links.paths {
|
||||
println(path_obj.path)
|
||||
}
|
||||
```
|
||||
|
||||
#### 5. Listing Only Directories or Only Files
|
||||
|
||||
Use `dirs_only` or `files_only` to restrict the results to only directories or only files.
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
|
||||
mut dir := pathlib.get('/some/directory')!
|
||||
|
||||
// List only directories (recursive)
|
||||
mut only_dirs := dir.list(
|
||||
dirs_only: true
|
||||
)!
|
||||
|
||||
// List only files (non-recursive)
|
||||
mut only_files := dir.list(
|
||||
files_only: true,
|
||||
recursive: false
|
||||
)!
|
||||
|
||||
for path_obj in only_dirs.paths {
|
||||
println(path_obj.path)
|
||||
}
|
||||
```
|
||||
|
||||
By combining these parameters, you can create highly specific and powerful file system listing operations tailored to your needs.
|
||||
204
aiprompts/herolib_advanced/redis.md
Normal file
204
aiprompts/herolib_advanced/redis.md
Normal file
@@ -0,0 +1,204 @@
|
||||
# Redisclient Module
|
||||
|
||||
The `redisclient` module in Herolib provides a comprehensive client for interacting with Redis, supporting various commands, caching, queues, and RPC mechanisms.
|
||||
|
||||
## Key Features
|
||||
|
||||
- **Direct Redis Commands**: Access to a wide range of Redis commands (strings, hashes, lists, keys, etc.).
|
||||
- **Caching**: Built-in caching mechanism with namespace support and expiration.
|
||||
- **Queues**: Simple queue implementation using Redis lists.
|
||||
- **RPC**: Remote Procedure Call (RPC) functionality over Redis queues for inter-service communication.
|
||||
|
||||
## Basic Usage
|
||||
|
||||
To get a Redis client instance, use `redisclient.core_get()`. By default, it connects to `127.0.0.1:6379`. You can specify a different address and port using the `RedisURL` struct.
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.core.redisclient
|
||||
|
||||
// Connect to default Redis instance (127.0.0.1:6379)
|
||||
mut redis := redisclient.core_get()!
|
||||
|
||||
// Or connect to a specific Redis instance
|
||||
// mut redis_url := redisclient.RedisURL{address: 'my.redis.server', port: 6380}
|
||||
// mut redis := redisclient.core_get(redis_url)!
|
||||
|
||||
// Example: Set and Get a key
|
||||
redis.set('mykey', 'myvalue')!
|
||||
value := redis.get('mykey')!
|
||||
// assert value == 'myvalue'
|
||||
|
||||
// Example: Check if a key exists
|
||||
exists := redis.exists('mykey')!
|
||||
// assert exists == true
|
||||
|
||||
// Example: Delete a key
|
||||
redis.del('mykey')!
|
||||
```
|
||||
|
||||
## Redis Commands
|
||||
|
||||
The `Redis` object provides methods for most standard Redis commands. Here are some examples:
|
||||
|
||||
### String Commands
|
||||
|
||||
- `set(key string, value string) !`: Sets the string value of a key.
|
||||
- `get(key string) !string`: Gets the string value of a key.
|
||||
- `set_ex(key string, value string, ex string) !`: Sets a key with an expiration time in seconds.
|
||||
- `incr(key string) !int`: Increments the integer value of a key by one.
|
||||
- `decr(key string) !int`: Decrements the integer value of a key by one.
|
||||
- `append(key string, value string) !int`: Appends a value to a key.
|
||||
- `strlen(key string) !int`: Gets the length of the value stored in a key.
|
||||
|
||||
```v
|
||||
redis.set('counter', '10')!
|
||||
redis.incr('counter')! // counter is now 11
|
||||
val := redis.get('counter')! // "11"
|
||||
```
|
||||
|
||||
### Hash Commands
|
||||
|
||||
- `hset(key string, skey string, value string) !`: Sets the string value of a hash field.
|
||||
- `hget(key string, skey string) !string`: Gets the value of a hash field.
|
||||
- `hgetall(key string) !map[string]string`: Gets all fields and values in a hash.
|
||||
- `hexists(key string, skey string) !bool`: Checks if a hash field exists.
|
||||
- `hdel(key string, skey string) !int`: Deletes one or more hash fields.
|
||||
|
||||
```v
|
||||
redis.hset('user:1', 'name', 'John Doe')!
|
||||
redis.hset('user:1', 'email', 'john@example.com')!
|
||||
user_name := redis.hget('user:1', 'name')! // "John Doe"
|
||||
user_data := redis.hgetall('user:1')! // map['name':'John Doe', 'email':'john@example.com']
|
||||
```
|
||||
|
||||
### List Commands
|
||||
|
||||
- `lpush(key string, element string) !int`: Inserts all specified values at the head of the list stored at key.
|
||||
- `rpush(key string, element string) !int`: Inserts all specified values at the tail of the list stored at key.
|
||||
- `lpop(key string) !string`: Removes and returns the first element of the list stored at key.
|
||||
- `rpop(key string) !string`: Removes and returns the last element of the list stored at key.
|
||||
- `llen(key string) !int`: Gets the length of a list.
|
||||
- `lrange(key string, start int, end int) ![]resp.RValue`: Gets a range of elements from a list.
|
||||
|
||||
```v
|
||||
redis.lpush('mylist', 'item1')!
|
||||
redis.rpush('mylist', 'item2')!
|
||||
first_item := redis.lpop('mylist')! // "item1"
|
||||
```
|
||||
|
||||
### Set Commands
|
||||
|
||||
- `sadd(key string, members []string) !int`: Adds the specified members to the set stored at key.
|
||||
- `smismember(key string, members []string) ![]int`: Returns if member is a member of the set stored at key.
|
||||
|
||||
```v
|
||||
redis.sadd('myset', ['member1', 'member2'])!
|
||||
is_member := redis.smismember('myset', ['member1', 'member3'])! // [1, 0]
|
||||
```
|
||||
|
||||
### Key Management
|
||||
|
||||
- `keys(pattern string) ![]string`: Finds all keys matching the given pattern.
|
||||
- `del(key string) !int`: Deletes a key.
|
||||
- `expire(key string, seconds int) !int`: Sets a key's time to live in seconds.
|
||||
- `ttl(key string) !int`: Gets the time to live for a key in seconds.
|
||||
- `flushall() !`: Deletes all the keys of all the existing databases.
|
||||
- `flushdb() !`: Deletes all the keys of the currently selected database.
|
||||
- `selectdb(database int) !`: Changes the selected database.
|
||||
|
||||
```v
|
||||
redis.set('temp_key', 'value')!
|
||||
redis.expire('temp_key', 60)! // Expires in 60 seconds
|
||||
```
|
||||
|
||||
## Redis Cache
|
||||
|
||||
The `RedisCache` struct provides a convenient way to implement caching using Redis.
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.core.redisclient
|
||||
|
||||
mut redis := redisclient.core_get()!
|
||||
mut cache := redis.cache('my_app_cache')
|
||||
|
||||
// Set a value in cache with expiration (e.g., 3600 seconds)
|
||||
cache.set('user:profile:123', '{ "name": "Alice" }', 3600)!
|
||||
|
||||
// Get a value from cache
|
||||
cached_data := cache.get('user:profile:123') or {
|
||||
// Cache miss, fetch from source
|
||||
println('Cache miss for user:profile:123')
|
||||
return
|
||||
}
|
||||
// println('Cached data: ${cached_data}')
|
||||
|
||||
// Check if a key exists in cache
|
||||
exists := cache.exists('user:profile:123')
|
||||
// assert exists == true
|
||||
|
||||
// Reset the cache for the namespace
|
||||
cache.reset()!
|
||||
```
|
||||
|
||||
## Redis Queue
|
||||
|
||||
The `RedisQueue` struct provides a simple queue mechanism using Redis lists.
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.core.redisclient
|
||||
import time
|
||||
|
||||
mut redis := redisclient.core_get()!
|
||||
mut my_queue := redis.queue_get('my_task_queue')
|
||||
|
||||
// Add items to the queue
|
||||
my_queue.add('task1')!
|
||||
my_queue.add('task2')!
|
||||
|
||||
// Get an item from the queue with a timeout (e.g., 1000 milliseconds)
|
||||
task := my_queue.get(1000)!
|
||||
// assert task == 'task1'
|
||||
|
||||
// Pop an item without timeout (returns error if no item)
|
||||
task2 := my_queue.pop()!
|
||||
// assert task2 == 'task2'
|
||||
```
|
||||
|
||||
## Redis RPC
|
||||
|
||||
The `RedisRpc` struct enables Remote Procedure Call (RPC) over Redis, allowing services to communicate by sending messages to queues and waiting for responses.
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.core.redisclient
|
||||
import json
|
||||
import time
|
||||
|
||||
mut redis := redisclient.core_get()!
|
||||
mut rpc_client := redis.rpc_get('my_rpc_service')
|
||||
|
||||
// Define a function to process RPC requests (server-side)
|
||||
fn my_rpc_processor(cmd string, data string) !string {
|
||||
// Simulate some processing based on cmd and data
|
||||
return 'Processed: cmd=${cmd}, data=${data}'
|
||||
}
|
||||
|
||||
// --- Client Side (calling the RPC) ---
|
||||
// Call the RPC service
|
||||
response := rpc_client.call(
|
||||
cmd: 'greet',
|
||||
data: '{"name": "World"}',
|
||||
wait: true,
|
||||
timeout: 5000 // 5 seconds timeout
|
||||
)!
|
||||
// println('RPC Response: ${response}')
|
||||
// assert response == 'Processed: cmd=greet, data={"name": "World"}'
|
||||
|
||||
// --- Server Side (processing RPC requests) ---
|
||||
// In a separate goroutine or process, you would run:
|
||||
// rpc_client.process(my_rpc_processor, timeout: 0)! // timeout 0 means no timeout, keeps processing
|
||||
|
||||
// Example of how to process a single request (for testing/demonstration)
|
||||
// In a real application, this would be in a loop or a background worker
|
||||
// return_queue_name := rpc_client.process(my_rpc_processor, timeout: 1000)!
|
||||
// result := rpc_client.result(1000, return_queue_name)!
|
||||
// println('Processed result: ${result}')
|
||||
150
aiprompts/herolib_core/core_paths.md
Normal file
150
aiprompts/herolib_core/core_paths.md
Normal file
@@ -0,0 +1,150 @@
|
||||
# Pathlib Usage Guide
|
||||
|
||||
## Overview
|
||||
|
||||
The pathlib module provides a comprehensive interface for handling file system operations. Key features include:
|
||||
|
||||
- Robust path handling for files, directories, and symlinks
|
||||
- Support for both absolute and relative paths
|
||||
- Automatic home directory expansion (~)
|
||||
- Recursive directory operations
|
||||
- Path filtering and listing
|
||||
- File and directory metadata access
|
||||
|
||||
## Basic Usage
|
||||
|
||||
### Importing pathlib
|
||||
```v
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
```
|
||||
|
||||
### Creating Path Objects
|
||||
```v
|
||||
// Create a Path object for a file
|
||||
mut file_path := pathlib.get("path/to/file.txt")
|
||||
|
||||
// Create a Path object for a directory
|
||||
mut dir_path := pathlib.get("path/to/directory")
|
||||
```
|
||||
|
||||
### Basic Path Operations
|
||||
```v
|
||||
// Get absolute path
|
||||
abs_path := file_path.absolute()
|
||||
|
||||
// Get real path (resolves symlinks)
|
||||
real_path := file_path.realpath()
|
||||
|
||||
// Check if path exists
|
||||
if file_path.exists() {
|
||||
// Path exists
|
||||
}
|
||||
```
|
||||
|
||||
## Path Properties and Methods
|
||||
|
||||
### Path Types
|
||||
```v
|
||||
// Check if path is a file
|
||||
if file_path.is_file() {
|
||||
// Handle as file
|
||||
}
|
||||
|
||||
// Check if path is a directory
|
||||
if dir_path.is_dir() {
|
||||
// Handle as directory
|
||||
}
|
||||
|
||||
// Check if path is a symlink
|
||||
if file_path.is_link() {
|
||||
// Handle as symlink
|
||||
}
|
||||
```
|
||||
|
||||
### Path Normalization
|
||||
```v
|
||||
// Normalize path (remove extra slashes, resolve . and ..)
|
||||
normalized_path := file_path.path_normalize()
|
||||
|
||||
// Get path directory
|
||||
dir_path := file_path.path_dir()
|
||||
|
||||
// Get path name without extension
|
||||
name_no_ext := file_path.name_no_ext()
|
||||
```
|
||||
|
||||
## File and Directory Operations
|
||||
|
||||
### File Operations
|
||||
```v
|
||||
// Write to file
|
||||
file_path.write("Content to write")!
|
||||
|
||||
// Read from file
|
||||
content := file_path.read()!
|
||||
|
||||
// Delete file
|
||||
file_path.delete()!
|
||||
```
|
||||
|
||||
### Directory Operations
|
||||
```v
|
||||
// Create directory
|
||||
mut dir := pathlib.get_dir(
|
||||
path: "path/to/new/dir"
|
||||
create: true
|
||||
)!
|
||||
|
||||
// List directory contents
|
||||
mut dir_list := dir.list()!
|
||||
|
||||
// Delete directory
|
||||
dir.delete()!
|
||||
```
|
||||
|
||||
### Symlink Operations
|
||||
```v
|
||||
// Create symlink
|
||||
file_path.link("path/to/symlink", delete_exists: true)!
|
||||
|
||||
// Resolve symlink
|
||||
real_path := file_path.realpath()
|
||||
```
|
||||
|
||||
## Advanced Operations
|
||||
|
||||
### Path Copying
|
||||
```v
|
||||
// Copy file to destination
|
||||
file_path.copy(dest: "path/to/destination")!
|
||||
```
|
||||
|
||||
### Recursive Operations
|
||||
```v
|
||||
// List directory recursively
|
||||
mut recursive_list := dir.list(recursive: true)!
|
||||
|
||||
// Delete directory recursively
|
||||
dir.delete()!
|
||||
```
|
||||
|
||||
### Path Filtering
|
||||
```v
|
||||
// List files matching pattern
|
||||
mut filtered_list := dir.list(
|
||||
regex: [r".*\.txt$"],
|
||||
recursive: true
|
||||
)!
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Error Handling
|
||||
```v
|
||||
if file_path.exists() {
|
||||
// Safe to operate
|
||||
} else {
|
||||
// Handle missing file
|
||||
}
|
||||
```
|
||||
|
||||
@@ -15,3 +15,4 @@ the files are in ~/code/github/freeflowuniverse/herolib/examples for herolib
|
||||
|
||||
- never use fn main() in a .vsh script
|
||||
- always use the top line as in example above
|
||||
- these scripts can be executed as is but can also use vrun $pathOfFile
|
||||
|
||||
11
aiprompts/herolib_core/example_script_curdir.md
Normal file
11
aiprompts/herolib_core/example_script_curdir.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Getting the Current Script's Path in Herolib/V Shell
|
||||
|
||||
can be used in any .v or .vsh script, easy to find content close to the script itself.
|
||||
|
||||
```v
|
||||
#!/usr/bin/env vsh
|
||||
|
||||
const script_path = os.dir(@FILE) + '/scripts'
|
||||
echo "Current scripts directory: ${script_directory}"
|
||||
|
||||
```
|
||||
@@ -18,8 +18,15 @@ when I generate vlang scripts I will always use .vsh extension and use following
|
||||
- in .vsh file there is no need for a main() function
|
||||
- these scripts can be used for examples or instruction scripts e.g. an installs script
|
||||
|
||||
## executing vlang scripts
|
||||
|
||||
## when creating a test script
|
||||
As AI agent I should also execute v or .vsh scripts with vrun
|
||||
|
||||
```bash
|
||||
vrun ~/code/github/freeflowuniverse/herolib/examples/biztools/bizmodel.vsh
|
||||
```
|
||||
|
||||
## executing test scripts
|
||||
|
||||
instruct user to test as follows (vtest is an alias which gets installed when herolib gets installed), can be done for a dir and for a file
|
||||
|
||||
|
||||
45
aiprompts/v_advanced/compress.md
Normal file
45
aiprompts/v_advanced/compress.md
Normal file
@@ -0,0 +1,45 @@
|
||||
The `compress` module in V provides low-level functionalities for compressing and decompressing byte arrays.
|
||||
|
||||
**Functions Overview (Low-Level):**
|
||||
|
||||
* **`compress(data []u8, flags int) ![]u8`**: Compresses an array of bytes.
|
||||
* **`decompress(data []u8, flags int) ![]u8`**: Decompresses an array of bytes.
|
||||
* **`decompress_with_callback(data []u8, cb ChunkCallback, userdata voidptr, flags int) !u64`**: Decompresses byte arrays using a callback function for chunks.
|
||||
|
||||
**Type Definition (Low-Level):**
|
||||
|
||||
* **`ChunkCallback`**: A function type `fn (chunk []u8, userdata voidptr) int` used to receive decompressed chunks.
|
||||
|
||||
---
|
||||
|
||||
**`compress.gzip` Module (High-Level Gzip Operations):**
|
||||
|
||||
For high-level gzip compression and decompression, use the `compress.gzip` module. This module provides a more convenient and recommended way to handle gzip operations compared to the low-level `compress` module.
|
||||
|
||||
**Key Features of `compress.gzip`:**
|
||||
|
||||
* **`compress(data []u8, params CompressParams) ![]u8`**: Compresses data using gzip, allowing specification of `CompressParams` like `compression_level` (0-4095).
|
||||
* **`decompress(data []u8, params DecompressParams) ![]u8`**: Decompresses gzip-compressed data, allowing specification of `DecompressParams` for verification.
|
||||
* **`decompress_with_callback(data []u8, cb compr.ChunkCallback, userdata voidptr, params DecompressParams) !int`**: Decompresses gzip data with a callback for chunks, similar to the low-level version but for gzip streams.
|
||||
* **`validate(data []u8, params DecompressParams) !GzipHeader`**: Validates a gzip header and returns its details.
|
||||
|
||||
**Parameter Structures:**
|
||||
|
||||
* **`CompressParams`**: Configures compression, primarily `compression_level` (0-4095).
|
||||
* **`DecompressParams`**: Configures decompression, including `verify_header_checksum`, `verify_length`, and `verify_checksum`.
|
||||
* **`GzipHeader`**: Represents the structure of a gzip header.
|
||||
|
||||
**Inline Code Example (Gzip Compression/Decompression):**
|
||||
|
||||
```v
|
||||
import compress.gzip
|
||||
|
||||
data := 'Hello, Gzip!'
|
||||
compressed := gzip.compress(data.bytes(), compression_level: 4095)!
|
||||
decompressed := gzip.decompress(compressed)!
|
||||
|
||||
// Check if decompressed data matches original
|
||||
// if data.bytes() == decompressed { ... }
|
||||
```
|
||||
|
||||
**Important Note:** Always prefer `compress.gzip` for general gzip compression/decompression tasks over the low-level `compress` module.
|
||||
12
examples/biztools/bizmodel_complete.vsh
Executable file
12
examples/biztools/bizmodel_complete.vsh
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
import freeflowuniverse.herolib.biz.bizmodel
|
||||
import os
|
||||
|
||||
|
||||
heroscript := os.join_path(os.dir(@FILE), 'examples/complete.heroscript')
|
||||
|
||||
// Execute the script and print results
|
||||
bizmodel.play(heroscript_path:heroscript)!
|
||||
mut bm := bizmodel.get("threefold")!
|
||||
bm.sheet.pprint(nr_columns: 25)!
|
||||
52
examples/biztools/examples/complete.heroscript
Normal file
52
examples/biztools/examples/complete.heroscript
Normal file
@@ -0,0 +1,52 @@
|
||||
// Define departments
|
||||
!!bizmodel.department_define bizname:'threefold' name:'engineering' descr:'Engineering Department'
|
||||
!!bizmodel.department_define bizname:'threefold' name:'operations' descr:'Operations Department'
|
||||
!!bizmodel.department_define bizname:'threefold' name:'sales' descr:'Sales Department'
|
||||
!!bizmodel.department_define bizname:'threefold' name:'admin' descr:'Administrative Department'
|
||||
|
||||
// Define engineering team with 10 people growing 10%/year (max 20)
|
||||
!!bizmodel.employee_define bizname:'threefold' name:'engineering_team' descr:'Engineering Team'
|
||||
nrpeople:'0:10,12:11,24:12,36:13,48:14,60:15,72:16,84:17,96:18,108:19,120:20'
|
||||
cost:'5000USD'
|
||||
indexation:'10%'
|
||||
department:'engineering'
|
||||
|
||||
// Define operations team with 2 people and 4% of revenue
|
||||
!!bizmodel.employee_define bizname:'threefold' name:'operations_team' descr:'Operations Team'
|
||||
nrpeople:'2'
|
||||
cost:'2000USD'
|
||||
cost_percent_revenue:'4%'
|
||||
department:'operations'
|
||||
|
||||
// Define sales team (placeholder)
|
||||
!!bizmodel.employee_define bizname:'threefold' name:'sales_team' descr:'Sales Department'
|
||||
nrpeople:'3'
|
||||
cost:'4000USD'
|
||||
department:'sales'
|
||||
|
||||
// Define admin team (placeholder)
|
||||
!!bizmodel.employee_define bizname:'threefold' name:'admin_team' descr:'Administrative Team'
|
||||
nrpeople:'2'
|
||||
cost:'3000USD'
|
||||
department:'admin'
|
||||
|
||||
// Define revenue stream
|
||||
!!bizmodel.revenue_define bizname:'threefold' name:'cloud_services'
|
||||
descr:'Cloud Services Revenue'
|
||||
revenue:'10:10000,36:1000000'
|
||||
extrapolate:1
|
||||
// 5% annual growth after 3 years (36 months)
|
||||
// Manually define growth for 5 years: 1.05^1, 1.05^2, etc.
|
||||
// This is a simplified representation
|
||||
// Actual implementation would need precise month:amount pairs
|
||||
|
||||
// Define travel cost at 3% of revenue
|
||||
!!bizmodel.cost_define bizname:'threefold' name:'travel_cost'
|
||||
descr:'Travel Expenses'
|
||||
cost_percent_revenue:'3%'
|
||||
|
||||
// Define initial funding
|
||||
!!bizmodel.funding_define bizname:'threefold' name:'initial_funding'
|
||||
descr:'Initial Funding'
|
||||
investment:'0:5000000'
|
||||
type:'capital'
|
||||
29
examples/compress_gzip_example.vsh
Normal file
29
examples/compress_gzip_example.vsh
Normal file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env -S v -cg -gc none -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
import freeflowuniverse.herolib...
|
||||
import compress.gzip
|
||||
|
||||
// Define some sample data to compress
|
||||
data := 'Hello, VLang Gzip Compression Example! This is some sample text to be compressed and then decompressed.'
|
||||
|
||||
println('Original Data: "${data}"')
|
||||
println('Original Data Length: ${data.len}')
|
||||
|
||||
// Compress the data using gzip
|
||||
// Using a compression_level of 4095 for best compression
|
||||
compressed_data := gzip.compress(data.bytes(), compression_level: 4095)!
|
||||
|
||||
println('Compressed Data Length: ${compressed_data.len}')
|
||||
|
||||
// Decompress the data
|
||||
decompressed_data := gzip.decompress(compressed_data)!
|
||||
|
||||
println('Decompressed Data: "${decompressed_data.string()}"')
|
||||
println('Decompressed Data Length: ${decompressed_data.len}')
|
||||
|
||||
// Verify if the decompressed data matches the original data
|
||||
if data.bytes() == decompressed_data {
|
||||
println('Compression and decompression successful! Data matches.')
|
||||
} else {
|
||||
println('Error: Decompressed data does not match original data.')
|
||||
}
|
||||
@@ -68,7 +68,10 @@ addtoscript('alias vtest=', 'alias vtest=\'v -stats -enable-globals -show-c-outp
|
||||
eprintln('Failed to add vtest alias: ${err}')
|
||||
}
|
||||
|
||||
//alias vtest='v -gc none -stats -enable-globals -show-c-output -keepc -n -w -cg -o /tmp/tester.c -g -cc tcc test'
|
||||
// Add vrun alias
|
||||
addtoscript('alias vrun=', 'alias vrun=\'v -stats -enable-globals -show-c-output -n -w -cg -gc none -cc tcc run\' ') or {
|
||||
eprintln('Failed to add vrun alias: ${err}')
|
||||
}
|
||||
|
||||
addtoscript('HOME/hero/bin', 'export PATH="\$PATH:\$HOME/hero/bin"') or {
|
||||
eprintln('Failed to add path to hero, ${err}')
|
||||
|
||||
Reference in New Issue
Block a user