← Zurück zu den Projekten
#Types (
#Store Trait (
#Builtins (
Pact Runtime
#pact-runtime
Runtime support library for code generated by the pact-lang compiler.
When pact compile --runtime generates Rust code, that code imports pact_runtime::prelude::* and depends on the types, traits, and builtins defined here.
#What's Inside
#Types (src/types.rs)
| Type | Purpose |
|---|---|
Uuid |
Re-exported from the uuid crate (with serde support) |
ValidationError |
{ field: String, message: String } — returned by validation methods |
StoreError |
UniqueViolation { field } or NotFound { id } — returned by store operations |
#Store Trait (src/store.rs)
pub trait Store<T: Clone + HasId + HasUniqueFields> {
fn query_by_id(&self, id: &Uuid) -> Option<T>;
fn insert(&mut self, item: T) -> Result<T, StoreError>;
fn list_all(&self) -> Vec<T>;
fn delete(&mut self, id: &Uuid) -> Option<T>;
}
Types stored in a Store must implement:
HasId— providesfn id(&self) -> UuidHasUniqueFields— providesfn unique_fields(&self) -> Vec<(&'static str, String)>for unique constraint checking
InMemoryStore<T> is a HashMap-backed implementation that enforces unique constraints on insert and cleans them up on delete.
#Builtins (src/builtins.rs)
| Function | Signature | Purpose |
|---|---|---|
validate_uuid |
fn(&str) -> Result<Uuid, ValidationError> |
Parse a string as UUID |
non_empty |
fn(&[T]) -> bool |
Check if a slice is non-empty |
#Prelude
use pact_runtime::prelude::*; // Brings in: Uuid, ValidationError, StoreError, Store, HasId, // HasUniqueFields, InMemoryStore, validate_uuid, non_empty
#Usage
Add to your Cargo.toml:
[dependencies]
pact-runtime = { path = "../pact-runtime" }
#Building and Testing
cargo build cargo test # 8 tests
#How Generated Code Uses This
The pact compile --runtime command produces Rust that depends on pact-runtime. For example, a Pact type definition:
(type User (field id UUID :immutable :generated) (field name String :min-len 1 :max-len 200) (field email String :format :email :unique-within user-store))
Generates:
use pact_runtime::prelude::*;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User {
pub id: Uuid,
pub name: String,
pub email: String,
}
impl HasId for User {
fn id(&self) -> Uuid { self.id }
}
impl HasUniqueFields for User {
fn unique_fields(&self) -> Vec<(&'static str, String)> {
vec![("email", self.email.clone())]
}
}
impl User {
pub fn validate(&self) -> Vec<ValidationError> { /* ... */ }
pub fn validate_input(input: &CreateUserInput) -> Vec<ValidationError> { /* ... */ }
pub fn from_input(input: CreateUserInput) -> Self { /* ... */ }
}
And functions use Store<T> trait bounds:
pub fn get_user_by_id(store: &impl Store<User>, id: &str) -> GetUserByIdResult {
match validate_uuid(id) {
Err(_) => GetUserByIdResult::InvalidId { id: id.to_string() },
Ok(uuid) => match store.query_by_id(&uuid) {
None => GetUserByIdResult::NotFound { id: uuid.to_string() },
Some(u) => GetUserByIdResult::Ok(u),
},
}
}