Quick Start — Rust
This path generates a TeaQL Rust library and console application, tests both outputs, starts the SQLite-backed runtime, executes a generated query, performs an audited mutation, and regenerates after a model change.
Expected time: about 20–30 minutes after the Rust toolchain is installed.
Evidence boundary: the complete path was executed on 2026-07-13 with the versions below. It proves this combination, not a minimum Rust version or a support commitment for every provider.
| Component | Verified value |
|---|---|
| Generator Server | 20260813.034821 |
cargo-teaql | 2.0.11 |
| TeaQL runtime and SQLite provider | 4.2.8 |
| Rust toolchain used by the recorded run | nightly 1.99.0 |
| Generated crate edition | 2021 |
1. Prepare an Empty Working Directory
Run the commands in this guide from one project root. The examples assume this layout:
teaql-rust-quick-start/
├── model/main.xml
├── generated/
│ ├── rust-lib-core/
│ └── rust-app-console/
└── handwritten/rust-contract-harness/
Install a current Rust nightly toolchain, then pin the verified client:
rustup toolchain install nightly --profile minimal
rustup default nightly
cargo install cargo-teaql --version 2.0.11 --locked
cargo teaql --version
If your team uses another toolchain, qualify it separately rather than treating the recorded nightly as a published minimum-supported Rust version.
2. Create the Model
Create model/main.xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root alias_model_name="child_development_service"
chinese_name="User List Service"
english_name="User List Service"
data_service="sqlite"
name="demo-service"
org="yourcompany"
version="1.0.0"
_module_key="root">
<demo_sys
name="ChildDevelopment"
create_time="createTime()"
last_update_time="updateTime()"
_module_key="platform"
/>
<user_info
name="Philip"
platform="demo_sys()"
_module_key="platform"
/>
</root>
The model is the source of truth. Do not plan handwritten changes inside the generated directories.
3. Discover Targets and Evaluate
Generation targets are dynamic. Query the current service before selecting a target:
cargo teaql services
cargo teaql evaluate --input model/main.xml
The recorded catalog exposed rust-lib-core and rust-app-console. Use the
names returned by your current catalog if they differ. If evaluation prints a
Markdown report, read its first error and fix the model before generation.
4. Generate Sibling Outputs
cargo teaql rust-lib-core \
--input model/main.xml \
--output generated/rust-lib-core
cargo teaql rust-app-console \
--input model/main.xml \
--output generated/rust-app-console
Keep the two outputs as siblings. The verified console manifest refers to the
library through ../rust-lib-core/lib.
Inspect the emitted manifests before building:
rg 'teaql-|rusqlite|path = ' generated/rust-lib-core/lib/Cargo.toml
rg 'teaql-|path = ' generated/rust-app-console/Cargo.toml
The recorded output used TeaQL runtime/provider 4.1.1. The generated manifest
is the authority for the dependency set of your run.
5. Test and Start the Generated Application
cargo test --manifest-path generated/rust-lib-core/lib/Cargo.toml
cargo test --manifest-path generated/rust-app-console/Cargo.toml
For this model, the generated runtime declares
DEMO_SERVICE_CORE_DATABASE_URL. Start it with a local SQLite file:
DEMO_SERVICE_CORE_DATABASE_URL=sqlite:///tmp/teaql-rust-quick-start.db \
cargo run --manifest-path generated/rust-app-console/Cargo.toml
Success means the process prints its startup message, opens SQLite, ensures the
schema, and exits without an error. For a different model name, inspect
generated/rust-lib-core/lib/src/runtime.rs and use its generated
DATABASE_URL_ENV value rather than guessing the variable name.
6. Execute a Query and Audited Mutation
Keep application code outside generated output. Create
handwritten/rust-contract-harness/Cargo.toml:
[package]
name = "teaql-rust-contract-harness"
version = "0.1.0"
edition = "2021"
[dependencies]
demo_service_core = { package = "demo-service-core", path = "../../generated/rust-lib-core/lib" }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
Create handwritten/rust-contract-harness/src/main.rs:
use demo_service_core::request_support::AuditedSave;
use demo_service_core::teaql_core::Entity as _;
use demo_service_core::{service_runtime, Q, ServiceRuntimeConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let runtime = service_runtime(ServiceRuntimeConfig {
database_url: "sqlite:///tmp/teaql-rust-contract-harness.db".to_string(),
})
.await?;
let platforms = Q::demo_syses()
.comment("Query the generated initial platform")
.purpose("Find the parent identifier for an audited child mutation")
.execute_for_list(&runtime)
.await?;
let platform_id = platforms
.iter()
.next()
.ok_or("generated initial platform was not returned")?
.id();
let mut user = Q::user_info()
.comment("Create Quick Start user")
.purpose("Verify an audited child mutation")
.new_entity(&runtime);
user.update_name("Quick Start User");
user.update_platform_id(platform_id);
user.audit_as("Create Quick Start user").save(&runtime).await?;
let users = Q::user_info()
.comment("Query Quick Start users")
.purpose("Verify the audited child mutation was persisted")
.execute_for_list(&runtime)
.await?;
if !users.iter().any(|item| item.name() == "Quick Start User") {
return Err("saved user was not returned by the query".into());
}
println!("Quick Start query and audited mutation passed");
Ok(())
}
These method names were inspected in the output generated from this exact
model. For another model, read its generated q.rs, entity, and request files;
never infer pluralization or update_xxx names.
Run the harness:
cargo run --manifest-path handwritten/rust-contract-harness/Cargo.toml
Expected final line:
Quick Start query and audited mutation passed
The query order is significant: comment → purpose → execute_for_xxx.
Mutations must declare audit_as(...) before save(...) or update(...).
7. Change the Model and Regenerate
Advance the root version to 1.0.1, then add email and its audit-mask
metadata to user_info:
<user_info
name="Philip"
email="philip@example.com"
_audit_mask_fields="email"
platform="demo_sys()"
_module_key="platform"
/>
Evaluate and regenerate the library:
cargo teaql evaluate --input model/main.xml
cargo teaql rust-lib-core \
--input model/main.xml \
--output generated/rust-lib-core
cargo test --manifest-path generated/rust-lib-core/lib/Cargo.toml
Inspect the exact generated change:
rg 'update_email|get_email|audit_mask_fields' generated/rust-lib-core/lib/src
The verified regeneration emitted update_email, email expression/request
support, and audit_mask_fields = "email" without changing the TeaQL
dependency versions. Run the handwritten harness again to confirm the existing
query and mutation still work.
Known Generated-Template Boundary
The cargo-teaql 2.0.8 sample-data template observed in this run contains
queries with purpose but no comment. Do not repair that by editing generated
sample_data.rs. Preserve the evidence and report the template defect;
handwritten queries must continue to use the complete intent chain.
Completion Checklist
- The model evaluates without unresolved errors.
- Both dynamic targets generate into sibling directories.
- Both generated targets pass
cargo test. - The generated console starts against SQLite.
- The handwritten query and audited mutation pass.
- Regeneration exposes the expected email API and audit metadata.
- No generated file was used as a handwritten customization point.
Continue with Regenerate and Review, Rust Database Providers, or Troubleshoot First Run.