Files
compliance-scanner-agent/AGENTS.md
Sharang Parnerkar cea8f59e10 Add DAST, graph modules, toast notifications, and dashboard enhancements
Add DAST scanning and code knowledge graph features across the stack:
- compliance-dast and compliance-graph workspace crates
- Agent API handlers and routes for DAST targets/scans and graph builds
- Core models and traits for DAST and graph domains
- Dashboard pages for DAST targets/findings/overview and graph explorer/impact
- Toast notification system with auto-dismiss for async action feedback
- Button click animations and disabled states for better UX

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 13:53:50 +01:00

18 KiB

You are an expert 0.7 Dioxus assistant. Dioxus 0.7 changes every api in dioxus. Only use this up to date documentation. cx, Scope, and use_state are gone

Provide concise code examples with detailed descriptions

Dioxus Dependency

You can add Dioxus to your Cargo.toml like this:

[dependencies]
dioxus = { version = "0.7.1" }

[features]
default = ["web", "webview", "server"]
web = ["dioxus/web"]
webview = ["dioxus/desktop"]
server = ["dioxus/server"]

Launching your application

You need to create a main function that sets up the Dioxus runtime and mounts your root component.

use dioxus::prelude::*;

fn main() {
	dioxus::launch(App);
}

#[component]
fn App() -> Element {
	rsx! { "Hello, Dioxus!" }
}

Then serve with dx serve:

curl -sSL http://dioxus.dev/install.sh | sh
dx serve

UI with RSX

rsx! {
	div {
		class: "container", // Attribute
		color: "red", // Inline styles
		width: if condition { "100%" }, // Conditional attributes
		"Hello, Dioxus!"
	}
	// Prefer loops over iterators
	for i in 0..5 {
		div { "{i}" } // use elements or components directly in loops
	}
	if condition {
		div { "Condition is true!" } // use elements or components directly in conditionals
	}

	{children} // Expressions are wrapped in brace
	{(0..5).map(|i| rsx! { span { "Item {i}" } })} // Iterators must be wrapped in braces
}

Assets

The asset macro can be used to link to local files to use in your project. All links start with / and are relative to the root of your project.

rsx! {
	img {
		src: asset!("/assets/image.png"),
		alt: "An image",
	}
}

Styles

The document::Stylesheet component will inject the stylesheet into the <head> of the document

rsx! {
	document::Stylesheet {
		href: asset!("/assets/styles.css"),
	}
}

Components

Components are the building blocks of apps

  • Component are functions annotated with the #[component] macro.
  • The function name must start with a capital letter or contain an underscore.
  • A component re-renders only under two conditions:
    1. Its props change (as determined by PartialEq).
    2. An internal reactive state it depends on is updated.
#[component]
fn Input(mut value: Signal<String>) -> Element {
	rsx! {
		input {
            value,
			oninput: move |e| {
				*value.write() = e.value();
			},
			onkeydown: move |e| {
				if e.key() == Key::Enter {
					value.write().clear();
				}
			},
		}
	}
}

Each component accepts function arguments (props)

  • Props must be owned values, not references. Use String and Vec<T> instead of &str or &[T].
  • Props must implement PartialEq and Clone.
  • To make props reactive and copy, you can wrap the type in ReadOnlySignal. Any reactive state like memos and resources that read ReadOnlySignal props will automatically re-run when the prop changes.

State

A signal is a wrapper around a value that automatically tracks where it's read and written. Changing a signal's value causes code that relies on the signal to rerun.

Local State

The use_signal hook creates state that is local to a single component. You can call the signal like a function (e.g. my_signal()) to clone the value, or use .read() to get a reference. .write() gets a mutable reference to the value.

Use use_memo to create a memoized value that recalculates when its dependencies change. Memos are useful for expensive calculations that you don't want to repeat unnecessarily.

#[component]
fn Counter() -> Element {
	let mut count = use_signal(|| 0);
	let mut doubled = use_memo(move || count() * 2); // doubled will re-run when count changes because it reads the signal

	rsx! {
		h1 { "Count: {count}" } // Counter will re-render when count changes because it reads the signal
		h2 { "Doubled: {doubled}" }
		button {
			onclick: move |_| *count.write() += 1, // Writing to the signal rerenders Counter
			"Increment"
		}
		button {
			onclick: move |_| count.with_mut(|count| *count += 1), // use with_mut to mutate the signal
			"Increment with with_mut"
		}
	}
}

Context API

The Context API allows you to share state down the component tree. A parent provides the state using use_context_provider, and any child can access it with use_context

#[component]
fn App() -> Element {
	let mut theme = use_signal(|| "light".to_string());
	use_context_provider(|| theme); // Provide a type to children
	rsx! { Child {} }
}

#[component]
fn Child() -> Element {
	let theme = use_context::<Signal<String>>(); // Consume the same type
	rsx! {
		div {
			"Current theme: {theme}"
		}
	}
}

Async

For state that depends on an asynchronous operation (like a network request), Dioxus provides a hook called use_resource. This hook manages the lifecycle of the async task and provides the result to your component.

  • The use_resource hook takes an async closure. It re-runs this closure whenever any signals it depends on (reads) are updated
  • The Resource object returned can be in several states when read:
  1. None if the resource is still loading
  2. Some(value) if the resource has successfully loaded
let mut dog = use_resource(move || async move {
	// api request
});

match dog() {
	Some(dog_info) => rsx! { Dog { dog_info } },
	None => rsx! { "Loading..." },
}

Routing

All possible routes are defined in a single Rust enum that derives Routable. Each variant represents a route and is annotated with #[route("/path")]. Dynamic Segments can capture parts of the URL path as parameters by using :name in the route string. These become fields in the enum variant.

The Router<Route> {} component is the entry point that manages rendering the correct component for the current URL.

You can use the #[layout(NavBar)] to create a layout shared between pages and place an Outlet<Route> {} inside your layout component. The child routes will be rendered in the outlet.

#[derive(Routable, Clone, PartialEq)]
enum Route {
	#[layout(NavBar)] // This will use NavBar as the layout for all routes
		#[route("/")]
		Home {},
		#[route("/blog/:id")] // Dynamic segment
		BlogPost { id: i32 },
}

#[component]
fn NavBar() -> Element {
	rsx! {
		a { href: "/", "Home" }
		Outlet<Route> {} // Renders Home or BlogPost
	}
}

#[component]
fn App() -> Element {
	rsx! { Router::<Route> {} }
}
dioxus = { version = "0.7.1", features = ["router"] }

Fullstack

Fullstack enables server rendering and ipc calls. It uses Cargo features (server and a client feature like web) to split the code into a server and client binaries.

dioxus = { version = "0.7.1", features = ["fullstack"] }

Server Functions

Use the #[post] / #[get] macros to define an async function that will only run on the server. On the server, this macro generates an API endpoint. On the client, it generates a function that makes an HTTP request to that endpoint.

#[post("/api/double/:path/&query")]
async fn double_server(number: i32, path: String, query: i32) -> Result<i32, ServerFnError> {
	tokio::time::sleep(std::time::Duration::from_secs(1)).await;
	Ok(number * 2)
}

Hydration

Hydration is the process of making a server-rendered HTML page interactive on the client. The server sends the initial HTML, and then the client-side runs, attaches event listeners, and takes control of future rendering.

Errors

The initial UI rendered by the component on the client must be identical to the UI rendered on the server.

  • Use the use_server_future hook instead of use_resource. It runs the future on the server, serializes the result, and sends it to the client, ensuring the client has the data immediately for its first render.
  • Any code that relies on browser-specific APIs (like accessing localStorage) must be run after hydration. Place this code inside a use_effect hook.

Agent Guidelines for Rust Code Quality

This document provides guidelines for maintaining high-quality Rust code. These rules MUST be followed by all AI coding agents and contributors.

Your Core Principles

All code you write MUST be fully optimized.

"Fully optimized" includes:

  • maximizing algorithmic big-O efficiency for memory and runtime
  • using parallelization and SIMD where appropriate
  • following proper style conventions for Rust (e.g. maximizing code reuse (DRY))
  • no extra code beyond what is absolutely necessary to solve the problem the user provides (i.e. no technical debt)

If the code is not fully optimized before handing off to the user, you will be fined $100. You have permission to do another pass of the code if you believe it is not fully optimized.

Preferred Tools

  • Use cargo for project management, building, and dependency management.
  • Use indicatif to track long-running operations with progress bars. The message should be contextually sensitive.
  • Use serde with serde_json for JSON serialization/deserialization.
  • Use ratatui adnd crossterm for terminal applications/TUIs.
  • Use axum for creating any web servers or HTTP APIs.
    • Keep request handlers async, returning Result<Response, AppError> to centralize error handling.
    • Use layered extractors and shared state structs instead of global mutable data.
    • Add tower middleware (timeouts, tracing, compression) for observability and resilience.
    • Offload CPU-bound work to tokio::task::spawn_blocking or background services to avoid blocking the reactor.
  • When reporting errors to the console, use tracing::error! or log::error! instead of println!.
  • If designing applications with a web-based front end interface, e.g. compiling to WASM or using dioxus:
    • All deep computation MUST occur within Rust processes (i.e. the WASM binary or the dioxus app Rust process). NEVER use JavaScript for deep computation.
    • The front-end MUST use Pico CSS and vanilla JavaScript. NEVER use jQuery or any component-based frameworks such as React.
    • The front-end should prioritize speed and common HID guidelines.
    • The app should use adaptive light/dark themes by default, with a toggle to switch the themes.
    • The typography/theming of the application MUST be modern and unique, similar to that of popular single-page web/mobile. ALWAYS add an appropriate font for headers and body text. You may reference fonts from Google Fonts.
    • NEVER use the Pico CSS defaults as-is: a separate CSS/SCSS file is encouraged. The design MUST logically complement the semantics of the application use case.
    • ALWAYS rebuild the WASM binary if any underlying Rust code that affects it is touched.
  • For data processing:
    • ALWAYS use polars instead of other data frame libraries for tabular data manipulation.
    • If a polars dataframe will be printed, NEVER simultaneously print the number of entries in the dataframe nor the schema as it is redundant.
    • NEVER ingest more than 10 rows of a data frame at a time. Only analyze subsets of data to avoid overloading your memory context.
  • If using Python to implement Rust code using PyO3/maturin:
    • Rebuild the Python package with maturin after finishing all Rust code changes.
    • ALWAYS use uv for Python package management and to create a .venv if it is not present. NEVER use the base system Python installation.
    • Ensure .venv is added to .gitignore.
    • Ensure ipykernel and ipywidgets is installed in .venv for Jupyter Notebook compatability. This should not be in package requirements.
    • MUST keep functions focused on a single responsibility
    • NEVER use mutable objects (lists, dicts) as default argument values
    • Limit function parameters to 5 or fewer
    • Return early to reduce nesting
    • MUST use type hints for all function signatures (parameters and return values)
    • NEVER use Any type unless absolutely necessary
    • MUST run mypy and resolve all type errors
    • Use Optional[T] or T | None for nullable types

Code Style and Formatting

  • MUST use meaningful, descriptive variable and function names
  • MUST follow Rust API Guidelines and idiomatic Rust conventions
  • MUST use 4 spaces for indentation (never tabs)
  • NEVER use emoji, or unicode that emulates emoji (e.g. ✓, ✗). The only exception is when writing tests and testing the impact of multibyte characters.
  • Use snake_case for functions/variables/modules, PascalCase for types/traits, SCREAMING_SNAKE_CASE for constants
  • Limit line length to 100 characters (rustfmt default)
  • Assume the user is a Python expert, but a Rust novice. Include additional code comments around Rust-specific nuances that a Python developer may not recognize.

Documentation

  • MUST include doc comments for all public functions, structs, enums, and methods
  • MUST document function parameters, return values, and errors
  • Keep comments up-to-date with code changes
  • Include examples in doc comments for complex functions

Example doc comment:

/// Calculate the total cost of items including tax.
///
/// # Arguments
///
/// * `items` - Slice of item structs with price fields
/// * `tax_rate` - Tax rate as decimal (e.g., 0.08 for 8%)
///
/// # Returns
///
/// Total cost including tax
///
/// # Errors
///
/// Returns `CalculationError::EmptyItems` if items is empty
/// Returns `CalculationError::InvalidTaxRate` if tax_rate is negative
///
/// # Examples
///
/// ```
/// let items = vec![Item { price: 10.0 }, Item { price: 20.0 }];
/// let total = calculate_total(&items, 0.08)?;
/// assert_eq!(total, 32.40);
/// ```
pub fn calculate_total(items: &[Item], tax_rate: f64) -> Result<f64, CalculationError> {

Type System

  • MUST leverage Rust's type system to prevent bugs at compile time
  • NEVER use .unwrap() in library code; use .expect() only for invariant violations with a descriptive message
  • MUST use meaningful custom error types with thiserror
  • Use newtypes to distinguish semantically different values of the same underlying type
  • Prefer Option<T> over sentinel values

Error Handling

  • NEVER use .unwrap() in production code paths
  • MUST use Result<T, E> for fallible operations
  • MUST use thiserror for defining error types and anyhow for application-level errors
  • MUST propagate errors with ? operator where appropriate
  • Provide meaningful error messages with context using .context() from anyhow

Function Design

  • MUST keep functions focused on a single responsibility
  • MUST prefer borrowing (&T, &mut T) over ownership when possible
  • Limit function parameters to 5 or fewer; use a config struct for more
  • Return early to reduce nesting
  • Use iterators and combinators over explicit loops where clearer

Struct and Enum Design

  • MUST keep types focused on a single responsibility
  • MUST derive common traits: Debug, Clone, PartialEq where appropriate
  • Use #[derive(Default)] when a sensible default exists
  • Prefer composition over inheritance-like patterns
  • Use builder pattern for complex struct construction
  • Make fields private by default; provide accessor methods when needed

Testing

  • MUST write unit tests for all new functions and types
  • MUST mock external dependencies (APIs, databases, file systems)
  • MUST use the built-in #[test] attribute and cargo test
  • Follow the Arrange-Act-Assert pattern
  • Do not commit commented-out tests
  • Use #[cfg(test)] modules for test code

Imports and Dependencies

  • MUST avoid wildcard imports (use module::*) except for preludes, test modules (use super::*), and prelude re-exports
  • MUST document dependencies in Cargo.toml with version constraints
  • Use cargo for dependency management
  • Organize imports: standard library, external crates, local modules
  • Use rustfmt to automate import formatting

Rust Best Practices

  • NEVER use unsafe unless absolutely necessary; document safety invariants when used
  • MUST call .clone() explicitly on non-Copy types; avoid hidden clones in closures and iterators
  • MUST use pattern matching exhaustively; avoid catch-all _ patterns when possible
  • MUST use format! macro for string formatting
  • Use iterators and iterator adapters over manual loops
  • Use enumerate() instead of manual counter variables
  • Prefer if let and while let for single-pattern matching

Memory and Performance

  • MUST avoid unnecessary allocations; prefer &str over String when possible
  • MUST use Cow<'_, str> when ownership is conditionally needed
  • Use Vec::with_capacity() when the size is known
  • Prefer stack allocation over heap when appropriate
  • Use Arc and Rc judiciously; prefer borrowing

Concurrency

  • MUST use Send and Sync bounds appropriately
  • MUST prefer tokio for async runtime in async applications
  • MUST use rayon for CPU-bound parallelism
  • Avoid Mutex when RwLock or lock-free alternatives are appropriate
  • Use channels (mpsc, crossbeam) for message passing

Security

  • NEVER store secrets, API keys, or passwords in code. Only store them in .env.
    • Ensure .env is declared in .gitignore.
  • MUST use environment variables for sensitive configuration via dotenvy or std::env
  • NEVER log sensitive information (passwords, tokens, PII)
  • Use secrecy crate for sensitive data types

Version Control

  • MUST write clear, descriptive commit messages
  • NEVER commit commented-out code; delete it
  • NEVER commit debug println! statements or dbg! macros
  • NEVER commit credentials or sensitive data

Tools

  • MUST use rustfmt for code formatting
  • MUST use clippy for linting and follow its suggestions
  • MUST ensure code compiles with no warnings (use -D warnings flag in CI, not #![deny(warnings)] in source)
  • Use cargo for building, testing, and dependency management
  • Use cargo test for running tests
  • Use cargo doc for generating documentation
  • NEVER build with cargo build --features python: this will always fail. Instead, ALWAYS use maturin.

Before Committing

  • All tests pass (cargo test)
  • No compiler warnings (cargo build)
  • Clippy passes (cargo clippy -- -D warnings)
  • Code is formatted (cargo fmt --check)
  • If the project creates a Python package and Rust code is touched, rebuild the Python package (source .venv/bin/activate && maturin develop --release --features python)
  • If the project creates a WASM package and Rust code is touched, rebuild the WASM package (wasm-pack build --target web --out-dir web/pkg)
  • All public items have doc comments
  • No commented-out code or debug statements
  • No hardcoded credentials

Remember: Prioritize clarity and maintainability over cleverness.3