Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions .github/workflows/lambda-repo-security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@
# documentation.
# rust-clippy is a tool that runs a bunch of lints to catch common
# mistakes in your Rust code and help improve your Rust code.
# More details at https://github.com/rust-lang/rust-clippy
# More details at https://github.com/rust-lang/rust-clippy
# and https://rust-lang.github.io/rust-clippy/

name: rust fmt + clippy analyze

on:
push:
branches: [ "main" ]
branches: ["main"]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main" ]
branches: ["main"]
schedule:
- cron: '41 10 * * 5'
- cron: "41 10 * * 5"

jobs:
rust-clippy-analyze:
Expand All @@ -25,7 +25,7 @@ jobs:
permissions:
contents: read
security-events: write
actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
steps:
- name: Checkout code
uses: actions/checkout@v4
Expand All @@ -42,7 +42,9 @@ jobs:
run: cargo install clippy-sarif sarif-fmt

- name: Check formatting
run: cargo fmt --all --check
run: |
rustup component add rustfmt --toolchain nightly-2025-09-26
cargo +nightly-2025-09-26 fmt --all --check

- name: Run rust-clippy
run: |
Expand Down
70 changes: 62 additions & 8 deletions crates/lambda-rs-args/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![allow(clippy::needless_return)]
//! # Lambda Args
//! Lambda Args is a simple argument parser for Rust. It is designed to be
//! simple to use and primarily for use in lambda command line applications.
Expand All @@ -7,6 +8,18 @@ use std::{
fmt,
};

/// Configurable command‑line argument parser for Lambda tools and examples.
///
/// Features:
/// - Long/short flags with aliases (e.g., "-o", "--output")
/// - Positional arguments in declaration order
/// - Type‑aware parsing (`string`, `integer`, `float`, `boolean`, `count`, lists)
/// - Optional environment variable and config‑file integration
/// - Mutually exclusive groups and simple requires relationships
/// - Subcommands with their own parsers
///
/// Use the builder to register arguments and then call `parse` with a slice of
/// tokens (usually `std::env::args().collect()`).
pub struct ArgumentParser {
name: String,
description: String,
Expand All @@ -24,20 +37,32 @@ pub struct ArgumentParser {
}

#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
/// Supported value types for an argument definition.
pub enum ArgumentType {
/// `true`/`false` (or implied by presence when compiled as a flag).
Boolean,
/// 64‑bit signed integer.
Integer,
/// 32‑bit floating point number.
Float,
/// 64‑bit floating point number.
Double,
/// UTF‑8 string.
String,
/// Count of flag occurrences (e.g., `-vvv` => 3).
Count,
/// One or more strings (space‑separated tokens).
StringList,
/// One or more integers.
IntegerList,
/// One or more 32‑bit floats.
FloatList,
/// One or more 64‑bit floats.
DoubleList,
}

#[derive(Debug, Clone, PartialEq, PartialOrd)]
/// Parsed value container used in results and defaults.
pub enum ArgumentValue {
None,
Boolean(bool),
Expand Down Expand Up @@ -88,6 +113,7 @@ impl Into<f64> for ArgumentValue {
}

#[derive(Debug)]
/// Declarative definition for a single CLI argument or positional parameter.
pub struct Argument {
name: String,
description: String,
Expand All @@ -99,7 +125,11 @@ pub struct Argument {
}

impl Argument {
/// Creates a new argument where the name represents
/// Create a new argument definition.
///
/// The `name` should be the canonical identifier used in help/usage output
/// (for example, `--output` or `--count`). For positional parameters call
/// `as_positional()` when building.
pub fn new(name: &str) -> Self {
return Argument {
name: name.to_string(),
Expand All @@ -118,13 +148,13 @@ impl Argument {
return self;
}

/// Sets the type for the ArgumentParser to parse the arguments value into.
/// Sets the type the parser should use when converting the raw value.
pub fn with_type(mut self, arg_type: ArgumentType) -> Self {
self.arg_type = arg_type;
return self;
}

/// Sets the description (Help string) of the argument for
/// Set a human‑readable description used in help/usage output.
pub fn with_description(mut self, description: &str) -> Self {
self.description = description.to_string();
return self;
Expand Down Expand Up @@ -167,27 +197,33 @@ impl Argument {
return self.arg_type.clone();
}

/// Canonical name used for matching and display (e.g., `--output`).
pub fn name(&self) -> &str {
return self.name.as_ref();
}

/// Default value used when the argument is not present.
pub fn default_value(&self) -> ArgumentValue {
return self.default_value.clone();
}

/// Description shown in `usage()` output.
pub fn description(&self) -> &str {
return self.description.as_ref();
}

/// Declared aliases that resolve to this argument (e.g., `-o`).
pub fn aliases(&self) -> &Vec<String> {
&self.aliases
}
/// Whether the argument is positional (no leading `-`/`--`).
pub fn is_positional(&self) -> bool {
self.positional
}
}

#[derive(Debug, Clone)]
/// A single parsed argument result as `(name, value)`.
pub struct ParsedArgument {
name: String,
value: ArgumentValue,
Expand All @@ -205,6 +241,7 @@ impl ParsedArgument {
return self.name.clone();
}

/// Return a clone of the parsed value.
pub fn value(&self) -> ArgumentValue {
return self.value.clone();
}
Expand Down Expand Up @@ -240,17 +277,20 @@ impl ArgumentParser {
return self.args.len();
}

/// Add an author string displayed in `usage()`.
pub fn with_author(mut self, author: &str) -> Self {
self.authors.push(author.to_string());
self
}

// TODO(vmarcella): Add description to the name
/// Add a human‑readable description shown in `usage()`.
pub fn with_description(mut self, description: &str) -> Self {
self.description = description.to_string();
self
}

/// Register an argument definition with the parser.
pub fn with_argument(mut self, argument: Argument) -> Self {
let idx = self.args.len();
let name = argument.name().to_string();
Expand All @@ -264,7 +304,7 @@ impl ArgumentParser {
return self;
}

/// Set an environment variable prefix (e.g., "OBJ_LOADER").
/// Set an environment variable prefix to read defaults (e.g., "OBJ_LOADER").
pub fn with_env_prefix(mut self, prefix: &str) -> Self {
self.env_prefix = Some(prefix.to_string());
self
Expand All @@ -290,13 +330,13 @@ impl ArgumentParser {
self
}

/// Merge values from a simple key=value config file (optional).
/// Merge values from a simple `key=value` config file (optional).
pub fn with_config_file(mut self, path: &str) -> Self {
self.config_path = Some(path.to_string());
self
}

/// Add a subcommand parser.
/// Add a subcommand parser which activates on a matching first token.
pub fn with_subcommand(mut self, mut sub: ArgumentParser) -> Self {
sub.is_subcommand = true;
let key = sub.name.clone();
Expand Down Expand Up @@ -717,7 +757,7 @@ impl ArgumentParser {
})
}

/// Backwards-compatible panicking API. Prefer `parse` for non-panicking behavior.
/// Backwardscompatible panicking API. Prefer `parse` for nonpanicking use.
pub fn compile(self, args: &[String]) -> Vec<ParsedArgument> {
match self.parse(args) {
Ok(parsed) => parsed.into_vec(),
Expand Down Expand Up @@ -791,16 +831,23 @@ fn parse_value(arg: &Argument, raw: &str) -> Result<ArgumentValue, ArgsError> {
}

#[derive(Debug)]
/// Errors that may occur during argument parsing.
pub enum ArgsError {
/// An unknown flag or option was encountered.
UnknownArgument(String),
/// The same flag/option was specified more than once when not allowed.
DuplicateArgument(String),
/// A flag/option expecting a value did not receive one.
MissingValue(String),
/// A provided value could not be parsed into the expected type.
InvalidValue {
name: String,
expected: String,
value: String,
},
/// A required option or positional argument was not provided.
MissingRequired(String),
/// Help was requested; contains a preformatted usage string.
HelpRequested(String),
}

Expand Down Expand Up @@ -831,25 +878,28 @@ impl fmt::Display for ArgsError {

impl std::error::Error for ArgsError {}

/// A parsed arguments wrapper with typed getters.
/// Parsed arguments with typed getters and subcommand support.
#[derive(Debug, Clone)]
pub struct ParsedArgs {
values: Vec<ParsedArgument>,
subcommand: Option<(String, Box<ParsedArgs>)>,
}

impl ParsedArgs {
/// Convert into the raw underlying `(name, value)` vector.
pub fn into_vec(self) -> Vec<ParsedArgument> {
self.values
}

/// True if the named argument is present (and not `None`).
pub fn has(&self, name: &str) -> bool {
self
.values
.iter()
.any(|p| p.name == name && !matches!(p.value, ArgumentValue::None))
}

/// Get a `String` value by name, if present and typed as string.
pub fn get_string(&self, name: &str) -> Option<String> {
self
.values
Expand All @@ -861,6 +911,7 @@ impl ParsedArgs {
})
}

/// Get an `i64` value by name, if present and typed as integer.
pub fn get_i64(&self, name: &str) -> Option<i64> {
self
.values
Expand All @@ -872,6 +923,7 @@ impl ParsedArgs {
})
}

/// Get an `f32` value by name, if present and typed as float.
pub fn get_f32(&self, name: &str) -> Option<f32> {
self
.values
Expand All @@ -883,6 +935,7 @@ impl ParsedArgs {
})
}

/// Get an `f64` value by name, if present and typed as double.
pub fn get_f64(&self, name: &str) -> Option<f64> {
self
.values
Expand All @@ -894,6 +947,7 @@ impl ParsedArgs {
})
}

/// Get a `bool` value by name, if present and typed as boolean.
pub fn get_bool(&self, name: &str) -> Option<bool> {
self
.values
Expand Down
5 changes: 5 additions & 0 deletions crates/lambda-rs-logging/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ use std::{

use crate::LogLevel;

/// Pluggable sink for log records emitted by the `Logger`.
///
/// Implementors decide how to format and where to deliver messages for each
/// severity level.
pub trait Handler {
fn trace(&mut self, message: String);
fn debug(&mut self, message: String);
Expand Down Expand Up @@ -102,6 +106,7 @@ impl Handler for FileHandler {
}

#[derive(Debug, Clone, PartialEq, PartialOrd)]
/// A handler that prints colored log lines to stdout.
pub struct ConsoleHandler {
name: String,
}
Expand Down
1 change: 1 addition & 0 deletions crates/lambda-rs-logging/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![allow(clippy::needless_return)]
//! A simple logging library for lambda-rs crates.

use std::fmt::Debug;
Expand Down
7 changes: 7 additions & 0 deletions crates/lambda-rs-platform/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
#![allow(clippy::needless_return)]
//! Cross‑platform abstractions and utilities used by Lambda.
//!
//! This crate hosts thin wrappers around `winit` (windowing) and `wgpu`
//! (graphics) that provide consistent defaults and ergonomic builders, along
//! with shader compilation backends and small helper modules (e.g., OBJ
//! loading and random number generation).
pub mod obj;
pub mod rand;
pub mod shader;
Expand Down
4 changes: 4 additions & 0 deletions crates/lambda-rs-platform/src/obj/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
//! Minimal helpers for loading Wavefront OBJ assets.
//!
//! These functions are thin wrappers around the `obj` crate used by examples
//! and tooling to import meshes.
use std::{
fs::File,
io::BufReader,
Expand Down
4 changes: 4 additions & 0 deletions crates/lambda-rs-platform/src/rand/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
//! Random number utilities used by examples and tests.
//!
//! Functions here delegate to the `rand` crate to generate simple random
//! values and uniformly distributed sequences.
use rand::Rng;

/// Generate a random float within any given range.
Expand Down
2 changes: 2 additions & 0 deletions crates/lambda-rs-platform/src/winit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,15 @@ pub struct WindowSize {
pub physical: PhysicalSize<u32>,
}

/// Aggregated window handle with cached sizing and monitor metadata.
pub struct WindowHandle {
pub window_handle: Window,
pub size: WindowSize,
pub monitor_handle: MonitorHandle,
}

// Should we take the loop as a field right here? Probably a ref or something? IDK
/// Builder for constructing a `WindowHandle` from window properties.
pub struct WindowHandleBuilder {
window_handle: Option<Window>,
size: WindowSize,
Expand Down
1 change: 1 addition & 0 deletions crates/lambda-rs/examples/minimal.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![allow(clippy::needless_return)]
//! Minimal application which configures a window & render context before
//! starting the runtime. You can use this as a starting point for your own
//! applications or to verify that your system is configured to run lambda
Expand Down
2 changes: 2 additions & 0 deletions crates/lambda-rs/examples/push_constants.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(clippy::needless_return)]

use lambda::{
component::Component,
events::WindowEvent,
Expand Down
Loading
Loading