Examples
This page contains practical examples of using rustico
in real-world scenarios.
About these examples
These examples demonstrate real-world use cases for rustico
. They're designed to be copy-paste friendly and show best practices for error handling.
Pro tip
Most examples use the @do
decorator for composing operations. This is the recommended approach for complex workflows.
Get Started with Examples View on GitHub
Web API Client
Use Case: Making HTTP requests with proper error handling
import requests
from rustico import as_result, do, Ok, Err, Result
@as_result(requests.RequestException)
def fetch_user(user_id: int) -> dict:
response = requests.get(f"https://api.example.com/users/{user_id}")
response.raise_for_status()
return response.json()
@as_result(KeyError, TypeError)
def extract_email(user_data: dict) -> str:
return user_data["email"]
@do
def get_user_email(user_id: int) -> Result[str, Exception]:
user_data = yield fetch_user(user_id)
email = yield extract_email(user_data)
return email.lower()
# Usage
result = get_user_email(123)
match result:
case Ok(email):
print(f"User email: {email}")
case Err(error):
if isinstance(error, requests.ConnectionError):
print("Network error. Please check your connection.")
elif isinstance(error, requests.HTTPError):
print(f"API error: {error}")
elif isinstance(error, KeyError):
print("User data is missing email field")
else:
print(f"Unexpected error: {error}")
Database Operations
Use Case: Safe database interactions with automatic connection handling
import sqlite3
from typing import List
from rustico import as_result, do, Ok, Err, Result
@as_result(sqlite3.Error)
def connect_db(db_path: str) -> sqlite3.Connection:
return sqlite3.connect(db_path)
@as_result(sqlite3.Error)
def execute_query(conn: sqlite3.Connection, query: str, params: tuple = ()) -> List[tuple]:
cursor = conn.cursor()
cursor.execute(query, params)
return cursor.fetchall()
@do
def get_user_posts(db_path: str, user_id: int) -> Result[List[dict], Exception]:
conn = yield connect_db(db_path)
try:
rows = yield execute_query(
conn,
"SELECT id, title, content FROM posts WHERE user_id = ?",
(user_id,)
)
posts = [
{"id": row[0], "title": row[1], "content": row[2]}
for row in rows
]
return posts
finally:
conn.close()
# Usage
result = get_user_posts("app.db", 42)
if result.is_ok():
posts = result.unwrap()
print(f"Found {len(posts)} posts")
for post in posts:
print(f"- {post['title']}")
else:
print(f"Database error: {result.unwrap_err()}")
File Operations
Use Case: Reading and parsing configuration files safely
import json
from pathlib import Path
from rustico import as_result, do, Ok, Err, Result
@as_result(FileNotFoundError, PermissionError)
def read_file(path: str) -> str:
return Path(path).read_text(encoding="utf-8")
@as_result(json.JSONDecodeError)
def parse_json(content: str) -> dict:
return json.loads(content)
@do
def load_config(config_path: str) -> Result[dict, Exception]:
content = yield read_file(config_path)
config = yield parse_json(content)
# Validate config
if "api_key" not in config:
return Err(ValueError("Missing required 'api_key' in config"))
return config
# Usage
result = load_config("config.json")
config = result.unwrap_or({
"api_key": "default_key",
"timeout": 30,
"debug": False
})
print(f"Using API key: {config['api_key']}")
Error Handling Patterns
Common Pitfalls
Remember that unwrap()
will raise an exception if called on an Err
result. Always check with is_ok()
first or use unwrap_or()
if you need a fallback value.
Fallback Values
from rustico import as_result, Ok, Err
@as_result(ValueError)
def parse_int(s: str) -> int:
return int(s)
# Using unwrap_or for fallback
port = parse_int(os.environ.get("PORT", "")).unwrap_or(8080)
print(f"Starting server on port {port}")
Transforming Errors
from rustico import as_result, Ok, Err
@as_result(ValueError)
def parse_int(s: str) -> int:
return int(s)
# Transform error to a user-friendly message
result = parse_int("abc").map_err(lambda e: f"Invalid number format: {e}")
print(result) # Err('Invalid number format: ...')
Collecting Results
from rustico import Ok, Err
def process_items(items: list) -> list:
results = [process_item(item) for item in items]
# Filter out successful results
successful = [result.unwrap() for result in results if result.is_ok()]
# Collect errors
errors = [result.unwrap_err() for result in results if result.is_err()]
if errors:
print(f"Warning: {len(errors)} items failed processing")
return successful
def process_item(item):
# Process the item and return Ok or Err
pass
Advanced Pattern Matching
Python 3.10+ Feature
Pattern matching requires Python 3.10 or later. For earlier versions, use conditional checks with is_ok()
and is_err()
.
from rustico import Ok, Err, as_result
@as_result(ValueError, ZeroDivisionError)
def divide(a: int, b: int) -> float:
return a / b
result = divide(10, 0)
match result:
case Ok(value):
print(f"Result: {value}")
case Err(ZeroDivisionError() as e):
print(f"Division by zero error: {e}")
case Err(ValueError() as e):
print(f"Value error: {e}")
case Err(e):
print(f"Unexpected error: {e}")
Working with External Libraries
Integration Pattern
When working with libraries that use exceptions, wrap their functions with as_result
or use a try/except block that returns Ok
/Err
.
from rustico import Ok, Err, Result
import requests
def fetch_data(url: str) -> Result[dict, Exception]:
try:
response = requests.get(url, timeout=5)
response.raise_for_status()
return Ok(response.json())
except requests.RequestException as e:
return Err(e)
# Usage
result = fetch_data("https://api.example.com/data")
data = result.unwrap_or({})
These examples demonstrate how rustico
can be used in various real-world scenarios to make error handling more explicit, composable, and maintainable.
Feature Comparison
Feature | Traditional Try/Except | rustico |
---|---|---|
Error Propagation | Manual re-raising | Automatic with @do |
Error Information | Often lost in translation | Preserved exactly |
Composability | Nested try/except blocks | Chainable operations |
Type Safety | No static analysis | Full type hints |
Pattern Matching | Not applicable | Native support |
Readability | Often verbose and nested | Linear and clear |
Next Steps
- Read the Quick Start guide for more examples
- Check the API Reference for detailed documentation
- Contribute to rustico to help improve the library