Ocre API index
Every public item of the ocre crate (all features) with its path, signature and
first doc sentence, grouped by module. Full documentation: the rustdoc pages, or
cargo doc -p ocre --all-features --open.
Generated by python3 scripts/api-index.py from rustdoc JSON; do not edit by hand.
ocre
ocre::serde_json(re-export): JSON values (serde_json::Value, thejson!macro) forjsonfields, without addingserde_jsonto the app.pub use serde_jsonocre::locales(macro): Declares the app’s locales as aLocalesstatic, compilinglocales/<code>.ymlinto the binary.macro_rules! localesocre::params(macro): Builds the parameter list of aDbquery:params![title, id].macro_rules! paramsocre::bulk(mod): Many rows in one D1 statement (Rails’insert_all,upsert_all, and anupdate_allwith a value per row).ocre::cache(mod): Caching: read-through values in Workers KV, HTTPCache-Control/ETagand 304 responses.ocre::config(mod): Typed app configuration from Worker variables and secrets, and the environment (development or production).ocre::encryption(mod): Attribute encryption for model columns: values are encrypted in Rust before they reach D1 and decrypted when rows are read, like Rails’encrypts.ocre::errors(mod): Error reporting (Rails’Rails.error): report errors with context to the logs and to services such as Sentry.ocre::events(mod): Structured events (Rails 8.1’sRails.event): named facts about what the app did, with a payload, for analytics, audit trails or a data warehouse.ocre::filters(mod, featurehtml): askama filters for Ocre’shelpers(featurehtml):{{ post.price|number_to_currency("$") }}.ocre::graphql(mod, featuregraphql): GraphQL support (featuregraphql).ocre::helpers(mod): View helpers: numbers, dates and text formatted like Rails’number_to_currency,time_ago_in_words,excerpt…ocre::i18n(mod): Translations:locales/*.yml,%{name}interpolation, plurals, locale per request.ocre::jobs(mod): Background jobs (Cloudflare Queues) and scheduled tasks (Cron Triggers).ocre::jwt(mod): JSON Web Tokens (HS256) for API clients.ocre::log(mod): Structured logging to Workers Logs: levels, request-scoped fields, JSON lines (Rails’Rails.loggerand tagged logging).ocre::mail(mod): Email: send with adapters (log, Resend, Cloudflare), receive from Email Routing.ocre::oauth(mod): “Sign in with GitHub / Google”: the OAuth 2.0 authorization code flow with PKCE.ocre::password(mod): Password hashing (PBKDF2-HMAC-SHA256).ocre::push(mod, featurepush): Web push notifications: messages a browser shows even when the app’s page is closed (the Push API, with the service worker ofocre g pwa).ocre::realtime(mod, featurerealtime): Realtime updates: WebSocket channels on a Durable Object, HTML broadcasts for htmx (featurerealtime).ocre::replicas(mod): D1 read replicas: reads go to a nearby copy of the database, writes to the primary, and each visitor still reads what they wrote (Rails’ automatic role switching, without a second database to configure).ocre::security(mod): Security helpers beyond whatservealways does: policies, rate limits, safe redirects, HTML cleaning.ocre::seo(mod): Search engines and language models: JSON-LD, sitemaps andllms.txt.ocre::sse(mod): Server-Sent Events: a response that sends events as they happen (Rails’ActionController::LivewithSSE).ocre::storage(mod): File storage in Cloudflare R2: multipart uploads, attachments, streamed downloads.ocre::testing(mod, featuretesting): Test helpers for Ocre apps, like Rails’ActionDispatch::IntegrationTestandActiveSupport::Testing: a request client for the running app, the test database, the server log, time travel and assertions.ocre::token(mod): Random tokens for emailed links and API keys, stored as digests.ocre::webhooks(mod): Webhooks: signatures for calls in both directions, and processing each event once.ocre::bool_from_sql(fn): Deserializes a SQLite boolean column (INTEGER 0/1) intobool.pub fn bool_from_sql<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<bool, D::Error>ocre::encode_path(fn): A route path with its non-ASCII characters percent-encoded, so Unicode routes match (Rails’ Unicode routes).pub fn encode_path(path: &str) -> Stringocre::error_page(fn, featurehtml): Renders error responses with the app’s own template (Rails’public/404.htmland500.html).pub fn error_page(response: Response, render: impl FnOnce(&ErrorPage) -> Result<Html<String>>) -> Responseocre::escape_like(fn): Escapes%,_and\sotextmatches literally in aLIKE ... ESCAPE '\'pattern (Rails’sanitize_sql_like).pub fn escape_like(text: &str) -> Stringocre::json_from_sql(fn): Deserializes a JSON column (the JSON text D1 returns) intoserde_json::Value.pub fn json_from_sql<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<serde_json::Value, D::Error>ocre::now(fn): Current Unix time in seconds, on Workers and in native tests.pub fn now() -> i64ocre::optional(fn): Deserializes an optional field wherenull, a missing value or an empty string isNone.pub fn optional<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error> where D: Deserializer<'de>, T: Deserialize<'de> + FromStr, T::Err: Displayocre::optional_json_from_sql(fn): Likejson_from_sqlfor aNULL-able JSON column:NULLisNone.pub fn optional_json_from_sql<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<Option<serde_json::Value>, D::Error>ocre::patch(fn): Deserializes a field of a partial update (PATCH) into keep / clear / set.pub fn patch<'de, D, T>(deserializer: D) -> Result<Option<Option<T>>, D::Error> where D: Deserializer<'de>, T: Deserialize<'de> + FromStr, T::Err: Displayocre::patch_json(fn): Deserializes an optional JSON field of a partial update into keep / clear / set.pub fn patch_json<'de, D>(deserializer: D) -> Result<Option<Option<serde_json::Value>>, D::Error> where D: Deserializer<'de>ocre::redirect_back(fn): Redirects to the page the request came from, or tofallback(Rails’redirect_back_or_to).pub fn redirect_back(headers: &HeaderMap, fallback: &str) -> Redirectocre::remote_ip(fn): The client’s IP address from theCF-Connecting-IPheader, for code that has the headers but no extractor.pub fn remote_ip(headers: &HeaderMap) -> Option<IpAddr>ocre::render(fn, featurehtml): Renders an askama template (compiled at build time) into an HTML response.pub fn render<T: Template>(template: &T) -> Result<Html<String>>ocre::serve(fn): Runs one request through the application router: the Workerfetchentry point.pub async fn serve(routes: Router<Ctx>, req: HttpRequest, env: Env) -> worker::Result<web_sys::Response>ocre::sleep(fn): Waitsdurationwithout using CPU (JavaScript’ssetTimeout): pacing forssestreams and polling.pub fn sleep(duration: std::time::Duration) -> impl Future<Output = ()> + Sendocre::ApiError(struct): Handler error for JSON endpoints: anErrorrendered as a JSON body.pub struct ApiError(pub Error)- Implements:
Debug,From,IntoResponse
- Implements:
ocre::Batches(struct): Batches of rows by increasing id, fromQuery::batches: Rails’find_in_batcheswithout holding a cursor open.pub struct Batches<T>ocre::Batches::resume_after(fn): Starts afterid(Rails’start:, exclusive), or from the first row withNone.pub fn resume_after(mut self, id: Option<i64>) -> Selfocre::Batches::after(fn): The last id read so far (Nonebefore the first batch).pub fn after(&self) -> Option<i64>ocre::Batches::is_done(fn): Whether the last batch was shorter than the batch size: no row is left.pub fn is_done(&self) -> boolocre::Batches::statement(fn): TheSELECTof the next batch.pub fn statement(&self) -> Statementocre::Batches::advance(fn): Records a batch just read: its last id, and whether it was the last batch.pub fn advance(&mut self, rows: &[T])ocre::Batches::next(fn): Runs the next batch: up to the batch size of rows after the last id read, orNoneonce every row was read.pub async fn next(&mut self, db: &Db) -> Result<Option<Vec<T>>>
ocre::Cookies(struct): The request’s cookies; what handlers set goes out with the response.pub struct Cookies(/* private fields */)ocre::Cookies::get(fn): The value of the plain cookiename.pub fn get(&self, name: &str) -> Option<String>ocre::Cookies::signed(fn): The value of the signed cookiename;Nonewhen absent or changed by the client.pub fn signed(&self, name: &str) -> Result<Option<String>>ocre::Cookies::encrypted(fn): The value of the encrypted cookiename;Nonewhen absent or changed by the client.pub fn encrypted(&self, name: &str) -> Result<Option<String>>ocre::Cookies::set(fn): Sets a plain cookie;max_ageNonemakes it last until the browser closes.pub fn set(&self, name: &str, value: &str, max_age: Option<Duration>) -> Result<()>ocre::Cookies::set_signed(fn): Sets a signed cookie: the browser sees the value, and a changed one reads asNone.pub fn set_signed(&self, name: &str, value: &str, max_age: Option<Duration>) -> Result<()>ocre::Cookies::set_encrypted(fn): Sets an encrypted cookie: the browser can neither read nor change the value.pub fn set_encrypted(&self, name: &str, value: &str, max_age: Option<Duration>) -> Result<()>ocre::Cookies::remove(fn): Deletes the cookienamefrom the browser.pub fn remove(&self, name: &str)- Implements:
Clone,FromRequestParts
ocre::Created(struct):201 Createdresponse with a JSON body, for create endpoints.pub struct Created<T>(pub T)- Implements:
IntoResponse
- Implements:
ocre::Ctx(struct): Per-request application context: the Worker environment with typed access to its bindings.pub struct Ctxocre::Ctx::log(fn): The logger of this request, job batch or cron run (seeocre::log).pub fn log(&self) -> &Loggerocre::Ctx::errors(fn): The error reporter of this request, job batch or cron run (seeocre::errors).pub fn errors(&self) -> &Reporterocre::Ctx::events(fn): Structured events of this request or job (Rails’Rails.event), seeocre::events.pub fn events(&self) -> &Eventsocre::Ctx::config(fn): The app’s settings, read from Worker variables and secrets intoT(seeocre::config).pub fn config<T: DeserializeOwned>(&self) -> Result<T>ocre::Ctx::env(fn): The raw Workers environment, for bindings Ocre does not wrap yet.pub fn env(&self) -> &Envocre::Ctx::secret(fn): The secretname, wherever it is kept: a Worker secret (ocre secrets push), a.dev.varsvalue inocre dev, or a secret of the account’s Secrets Store bound to the Worker in cloudflare.config.ts (NAME: bindings.secretsStoreSecret({ storeId, secretName }), whichocre secrets push NAME --storewrites).pub fn secret(&self, name: &str) -> impl Future<Output = Result<String>> + Send + use<>ocre::Ctx::db(fn): The application database: the D1 bindingDB.pub fn db(&self) -> Result<Db>ocre::Ctx::db_named(fn): Another D1 database of the app, by its binding name (Rails’ multiple databases).pub fn db_named(&self, binding: &str) -> Result<Db>- Implements:
Clone
ocre::Db(struct): Handle to the application’s D1 (SQLite) database, fromCtx::db.pub struct Dbocre::Db::uncached(fn): This handle without the per-request query cache: every query goes to D1.pub fn uncached(self) -> Selfocre::Db::all(fn): Runs a query and returns every row, deserialized intoT.pub fn all<'q, T: DeserializeOwned>(&self, sql: &'q str, params: Vec<Param>) -> impl Future<Output = Result<Vec<T>>> + Send + use<'q, T>ocre::Db::first(fn): Runs a query and returns its first row, if any, deserialized intoT.pub fn first<'q, T: DeserializeOwned>(&self, sql: &'q str, params: Vec<Param>) -> impl Future<Output = Result<Option<T>>> + Send + use<'q, T>ocre::Db::execute(fn): Runs a statement that returns no rows (INSERT,UPDATE,DELETE) and gives the number of rows changed.pub fn execute<'q>(&self, sql: &'q str, params: Vec<Param>) -> impl Future<Output = Result<usize>> + Send + use<'q>ocre::Db::exists(fn): Whether a query returns at least one row.pub fn exists<'q>(&self, sql: &'q str, params: Vec<Param>) -> impl Future<Output = Result<bool>> + Send + use<'q>ocre::Db::batch(fn): Runs every statement in one transaction and returns the rows changed by each one.pub fn batch(&self, statements: Vec<Statement>) -> impl Future<Output = Result<Vec<usize>>> + Send + '_
ocre::ErrorPage(struct, featurehtml): What an HTML error page may show: the status, a message safe for users, and validation errors.pub struct ErrorPageocre::ErrorPage::status(field): HTTP status of the response, e.g.404:{{ error.status.as_u16() }}in a template.pub status: StatusCodeocre::ErrorPage::message(field): Message for the user:Not found,Validation failed, a bad request’s own message…pub message: Stringocre::ErrorPage::fields(field): Field errors of a 422 ({{ field.full_message() }}), empty otherwise.pub fields: Vec<FieldError>- Implements:
Clone,Debug
ocre::FieldError(struct): One failed validation: the field name plus the message without it, as in Rails’errors.pub struct FieldErrorocre::FieldError::field(field): Field name as in the form or JSON body ("title","author_id").pub field: Stringocre::FieldError::message(field): Message without the field name ("can't be blank").pub message: Stringocre::FieldError::new(fn): Builds an error forfieldwithmessage(without the field name).pub fn new(field: impl Into<String>, message: impl Into<String>) -> Selfocre::FieldError::key(fn): The Rails translation key of the check that failed ("blank","too_long"…), if any.pub fn key(&self) -> Option<&'static str>ocre::FieldError::full_message(fn): The message prefixed with the humanized field name:"Title can't be blank".pub fn full_message(&self) -> String- Implements:
Clone,Debug,Display,PartialEq,Serialize
ocre::Flash(struct): Flash messages set by the previous request, as an extractor.pub struct Flash(/* private fields */)ocre::Flash::get(fn): The message of the givenkind, if the previous request set one.pub fn get(&self, kind: &str) -> Option<&str>ocre::Flash::notice(fn): Thenoticemessage (success), same asflash.get("notice").pub fn notice(&self) -> Option<&str>ocre::Flash::alert(fn): Thealertmessage (failure), same asflash.get("alert").pub fn alert(&self) -> Option<&str>ocre::Flash::iter(fn): Every(kind, message)pair.pub fn iter(&self) -> impl Iterator<Item = (&str, &str)>ocre::Flash::is_empty(fn): Whether there is no message.pub fn is_empty(&self) -> boolocre::Flash::now(fn): These messages plusmessageofkind, for this response only (Rails’flash.now): render a page with a message without storing it in the session, e.g. a form shown again with an alert.pub fn now(self, kind: &str, message: impl Into<String>) -> Self- Implements:
Clone,Debug,Default,Eq,FromRequestParts,PartialEq
ocre::Htmx(struct, featurehtml): Extractor telling whether htmx sent the request:Htmx(true)when it hasHX-Request: true.pub struct Htmx(pub bool)- Implements:
Clone,Copy,Debug,FromRequestParts
- Implements:
ocre::HxRedirect(struct, featurehtml): Response telling htmx to load another page:200 OKwith theHX-Redirectheader.pub struct HxRedirect(pub String)- Implements:
Clone,Debug,Eq,IntoResponse,PartialEq
- Implements:
ocre::Json(struct): JSON request body extractor and response, whose failures are JSON too.pub struct Json<T>(pub T)- Implements:
Clone,Copy,Debug,Default,FromRequest,IntoResponse
- Implements:
ocre::Markdown(struct): A Markdown response:text/markdown; charset=utf-8(Rails’render markdown:).pub struct Markdown(pub String)- Implements:
Clone,Debug,Eq,IntoResponse,PartialEq
- Implements:
ocre::NestedForm(struct): Form extractor for bracketed field names, like Rails’params(post[title],tag_ids[],lines[0][qty]).pub struct NestedForm<T>(pub T)ocre::NestedForm::parse(fn): Decodes anapplication/x-www-form-urlencodedstring (a body or a query string) with bracketed names.pub fn parse(input: &str) -> Result<T>- Implements:
Clone,Copy,Debug,Default,FromRequest
ocre::Page(struct):?limit=&offset=pagination for list endpoints, as an extractor.pub struct Pageocre::Page::limit(field): Rows to return,1..=100.pub limit: i64ocre::Page::offset(field): Rows to skip,0or more.pub offset: i64ocre::Page::DEFAULT_LIMIT(const):limitwhen the query string has none: 50.pub const DEFAULT_LIMIT: i64 = 50ocre::Page::MAX_LIMIT(const): Largest acceptedlimit: 100.pub const MAX_LIMIT: i64 = 100ocre::Page::new(fn): Builds a page after checking the bounds:1..=100forlimit,0..foroffset.pub fn new(limit: i64, offset: i64) -> Result<Self, Error>ocre::Page::next(fn): The page after this one, orNonewhenreturned(the rows this page got) is less thanlimit.pub fn next(&self, returned: usize) -> Option<Self>ocre::Page::previous(fn): The page before this one, orNoneon the first page.pub fn previous(&self) -> Option<Self>ocre::Page::query(fn): The query string of this page, without?:offset=50, withlimit=first when it is not the default.pub fn query(&self) -> Stringocre::Page::links(fn):Linkheader (RFC 8288) pointing JSON clients at thenext,prevandfirstpages ofpath.pub fn links(&self, path: &str, returned: usize) -> PageLinks- Implements:
Clone,Copy,Debug,FromRequestParts,PartialEq
ocre::PageLinks(struct): TheLinkheader built byPage::links, as a response part (nothing when there is no other page).pub struct PageLinks(/* private fields */)- Implements:
Clone,Debug,IntoResponseParts
- Implements:
ocre::Paginated(struct): A page of rows plus the total, for pagination links and JSON envelopes.pub struct Paginated<T>ocre::Paginated::items(field): The rows of this page.pub items: Vec<T>ocre::Paginated::total(field): Rows matching the query, all pages together.pub total: i64ocre::Paginated::limit(field): Rows per page.pub limit: i64ocre::Paginated::offset(field): Rows skipped before this page.pub offset: i64ocre::Paginated::current_page(fn): 1-based number of this page.pub fn current_page(&self) -> i64ocre::Paginated::total_pages(fn): Number of pages (at least 1, even with no row).pub fn total_pages(&self) -> i64ocre::Paginated::has_next(fn): Whether rows follow this page.pub fn has_next(&self) -> boolocre::Paginated::has_previous(fn): Whether rows come before this page.pub fn has_previous(&self) -> boolocre::Paginated::next_page(fn): The next page, if any.pub fn next_page(&self) -> Option<Page>ocre::Paginated::previous_page(fn): The previous page, if any (never a negative offset).pub fn previous_page(&self) -> Option<Page>ocre::Paginated::map(fn): Converts the items, keeping the counts (e.g. rows into view structs).pub fn map<U>(self, f: impl FnMut(T) -> U) -> Paginated<U>- Implements:
Clone,Debug,PartialEq,Serialize
ocre::Param(struct): A value bound to a?Nplaceholder of a D1 query.pub struct Param(/* private fields */)- Implements:
Clone,Debug,IntoParam,PartialEq
- Implements:
ocre::Query(struct): ASELECTon one table, built step by step, whose values are always bound parameters.pub struct Query<T>ocre::Query::table(fn): Starts a query ontable:SELECT * FROM <table>.pub fn table(table: &'static str) -> Selfocre::Query::scope(fn): Applies a scope:f(self).pub fn scope(self, f: impl FnOnce(Self) -> Self) -> Selfocre::Query::select(fn): Selectscolumns(an SQL select list) instead of*; the rows becomeU.pub fn select<U>(mut self, columns: &'static str) -> Query<U>ocre::Query::distinct(fn):SELECT DISTINCT: drops duplicate rows.pub fn distinct(mut self) -> Selfocre::Query::join(fn): Adds a join clause, written in full:JOIN ...orLEFT JOIN ....pub fn join(mut self, clause: &'static str) -> Selfocre::Query::eq(fn):column = value.pub fn eq(mut self, column: &'static str, value: impl IntoParam) -> Selfocre::Query::ne(fn):column != value.pub fn ne(mut self, column: &'static str, value: impl IntoParam) -> Selfocre::Query::gt(fn):column > value.pub fn gt(mut self, column: &'static str, value: impl IntoParam) -> Selfocre::Query::gte(fn):column >= value.pub fn gte(mut self, column: &'static str, value: impl IntoParam) -> Selfocre::Query::lt(fn):column < value.pub fn lt(mut self, column: &'static str, value: impl IntoParam) -> Selfocre::Query::lte(fn):column <= value.pub fn lte(mut self, column: &'static str, value: impl IntoParam) -> Selfocre::Query::between(fn):column BETWEEN low AND high, both bounds included.pub fn between(mut self, column: &'static str, low: impl IntoParam, high: impl IntoParam) -> Selfocre::Query::is_in(fn):column IN (?, ?, ...).pub fn is_in<V: IntoParam>(mut self, column: &'static str, values: impl IntoIterator<Item = V>) -> Selfocre::Query::not_in(fn):column NOT IN (?, ?, ...).pub fn not_in<V: IntoParam>(mut self, column: &'static str, values: impl IntoIterator<Item = V>) -> Selfocre::Query::is_null(fn):column IS NULL.pub fn is_null(mut self, column: &'static str) -> Selfocre::Query::is_not_null(fn):column IS NOT NULL.pub fn is_not_null(mut self, column: &'static str) -> Selfocre::Query::like(fn):column LIKE pattern, with the pattern as given:%and_are wildcards.pub fn like(mut self, column: &'static str, pattern: impl IntoParam) -> Selfocre::Query::not_like(fn):column NOT LIKE pattern(wildcards as given, seelike).pub fn not_like(mut self, column: &'static str, pattern: impl IntoParam) -> Selfocre::Query::contains(fn):columncontainstext(case-insensitive for ASCII), with%,_and\intextmatched literally (seeescape_like).pub fn contains(mut self, column: &'static str, text: &str) -> Selfocre::Query::starts_with(fn):columnstarts withtext(wildcards escaped, seecontains).pub fn starts_with(mut self, column: &'static str, text: &str) -> Selfocre::Query::ends_with(fn):columnends withtext(wildcards escaped, seecontains).pub fn ends_with(mut self, column: &'static str, text: &str) -> Selfocre::Query::where_sql(fn): Adds a raw SQL condition with bare?placeholders, bound toparamsin order.pub fn where_sql(mut self, fragment: &'static str, params: Vec<Param>) -> Selfocre::Query::where_associated(fn): Keeps rows with at least one row intablepointing to them throughforeign_key(Rails’where.associatedon a has-many side).pub fn where_associated(mut self, table: &'static str, foreign_key: &'static str) -> Selfocre::Query::where_missing(fn): Keeps rows that no row oftablepoints to throughforeign_key(Rails’where.missingon a has-many side): posts without comments.pub fn where_missing(mut self, table: &'static str, foreign_key: &'static str) -> Selfocre::Query::date_range(fn): Filterscolumnbetween two optional bounds, like Loco’sDateRangeBuilder.pub fn date_range<V: IntoParam>(self, column: &'static str, from: Option<V>, to: Option<V>) -> Selfocre::Query::unscope_where(fn): Removes every condition added so far (Rails’unscope(:where)); chain new ones after it for Rails’rewhere.pub fn unscope_where(mut self) -> Selfocre::Query::unscope_limit(fn): Removes the limit and offset set so far (Rails’unscope(:limit, :offset)).pub fn unscope_limit(mut self) -> Selfocre::Query::reverse_order(fn): Reverses the order (Rails’reverse_order):ASCterms becomeDESCand back; terms without a direction (order_in, a bareorder_sql) getDESC.pub fn reverse_order(mut self) -> Selfocre::Query::any(fn): Matches rows meeting at least one of the conditionsfadds:(a OR b ...).pub fn any(mut self, f: impl FnOnce(Self) -> Self) -> Selfocre::Query::not(fn): Matches rows that do not meet all the conditionsfadds:NOT (a AND b ...).pub fn not(mut self, f: impl FnOnce(Self) -> Self) -> Selfocre::Query::none(fn): Matches no row (WHERE 0), like Rails’none: a scope can return it when a filter makes the result empty.pub fn none(mut self) -> Selfocre::Query::group_by(fn):GROUP BY columns; combine withselectfor the aggregates andhavingto filter groups.pub fn group_by(mut self, columns: &'static str) -> Selfocre::Query::having(fn): Adds aHAVINGcondition (raw SQL with bare?placeholders) on the groups.pub fn having(mut self, fragment: &'static str, params: Vec<Param>) -> Selfocre::Query::order_asc(fn):ORDER BY column ASC, after any order already set.pub fn order_asc(self, column: &'static str) -> Selfocre::Query::order_desc(fn):ORDER BY column DESC, after any order already set.pub fn order_desc(self, column: &'static str) -> Selfocre::Query::order_by(fn):ORDER BY column <direction>, after any order already set.pub fn order_by(mut self, column: &'static str, direction: Direction) -> Selfocre::Query::order_in(fn): Orderscolumnby an explicit list of values (Rails’in_order_of): rows whose value is not listed come last.pub fn order_in<V: IntoParam>(mut self, column: &'static str, values: impl IntoIterator<Item = V>) -> Selfocre::Query::order_sql(fn): Adds a rawORDER BYterm, e.g.lower(title)orpublished_at DESC NULLS LAST.pub fn order_sql(mut self, term: &'static str) -> Selfocre::Query::reorder(fn): Removes the order set so far (Rails’reorderwhen followed by a new order).pub fn reorder(mut self) -> Selfocre::Query::limit(fn): Returns at mostlimitrows.pub fn limit(mut self, limit: i64) -> Selfocre::Query::offset(fn): Skips the firstoffsetrows.pub fn offset(mut self, offset: i64) -> Selfocre::Query::page(fn): Limit and offset from aPage(?limit=&offset=).pub fn page(self, page: Page) -> Selfocre::Query::explain_statement(fn):EXPLAIN QUERY PLANof theSELECT(Rails’explain): how SQLite finds the rows, e.g.SEARCH posts USING INDEX index_posts_on_author_id (author_id=?)or a fullSCAN posts.pub fn explain_statement(&self) -> Statementocre::Query::batches(fn): Walks the matching rows in batches ofsize, ordered by id (Rails’find_in_batches/in_batches, andfind_eachwith a loop over each batch).pub fn batches(self, size: i64, id: fn(&T) -> i64) -> Batches<T>ocre::Query::to_statement(fn): TheSELECTstatement, with placeholders numbered?1, ?2....pub fn to_statement(&self) -> Statementocre::Query::count_statement(fn):SELECT COUNT(*) AS countof the matching rows, ignoring order, limit and offset.pub fn count_statement(&self) -> Statementocre::Query::exists_statement(fn):SELECT 1 ... LIMIT 1: whether any row matches, stopping at the first.pub fn exists_statement(&self) -> Statementocre::Query::value_statement(fn):SELECT <expression> AS value, keeping conditions, order and limits: one column of every matching row (Rails’pluck), or with an aggregate expression (SUM(price)) the calculation over the matching rows (order and limits are dropped then, as they do not apply).pub fn value_statement(&self, expression: &'static str) -> Statementocre::Query::aggregate_statement(fn):SELECT <aggregate> AS valueover the matching rows, without order or limits.pub fn aggregate_statement(&self, expression: &'static str) -> Statementocre::Query::update_statement(fn):UPDATE <table> SET ... WHERE ...on the matching rows (Rails’update_all): no validation, noupdated_atchange unless listed.pub fn update_statement(&self, sets: Vec<(&'static str, Param)>) -> Statementocre::Query::delete_statement(fn):DELETE FROM <table> WHERE ...on the matching rows (Rails’delete_all).pub fn delete_statement(&self) -> Statementocre::Query::all(fn): Runs the query and returns every matching row.pub async fn all(&self, db: &Db) -> Result<Vec<T>>ocre::Query::first(fn): Runs the query withLIMIT 1and returns the first row, if any (Rails’first,takeandfind_by).pub async fn first(&self, db: &Db) -> Result<Option<T>>ocre::Query::paginate(fn): Runs the query and itscount_statementforpage: the rows plus the total for pagination links.pub async fn paginate(&self, db: &Db, page: Page) -> Result<Paginated<T>>ocre::Query::first_or_create(fn): Returns the first matching row, or runscreatewhen there is none (Rails’find_or_create_by; with aNew...value built in memory instead of saved,find_or_initialize_by).pub async fn first_or_create<F, Fut>(&self, db: &Db, create: F) -> Result<T> where F: FnOnce() -> Fut, Fut: Future<Output = Result<T>>ocre::Query::create_or_first(fn): Runscreatefirst and, when it fails because the value is already taken, returns the existing row instead (Rails’create_or_find_by).pub async fn create_or_first<F, Fut>(&self, db: &Db, create: F) -> Result<T> where F: FnOnce() -> Fut, Fut: Future<Output = Result<T>>ocre::Query::explain(fn): The query plan, one line per step (Rails’explain):SEARCHmeans an index is used,SCANa full table read.pub async fn explain(&self, db: &Db) -> Result<Vec<String>>ocre::Query::count(fn): Number of matching rows (COUNT(*)), ignoring order and limits.pub async fn count(&self, db: &Db) -> Result<i64>ocre::Query::exists(fn): Whether any row matches (SELECT 1 ... LIMIT 1; Rails’exists?/any?).pub async fn exists(&self, db: &Db) -> Result<bool>ocre::Query::pluck(fn): Values of one column (or expression) of the matching rows (Rails’pluck/ids).pub async fn pluck<V: DeserializeOwned>(&self, db: &Db, expression: &'static str) -> Result<Vec<V>>ocre::Query::aggregate(fn): An aggregate over the matching rows:SUM(price),AVG(rating),MIN(created_at),MAX(views),COUNT(DISTINCT author_id)…pub async fn aggregate<V: DeserializeOwned>(&self, db: &Db, expression: &'static str) -> Result<Option<V>>ocre::Query::update_all(fn): Updates every matching row without validation (Rails’update_all) and returns how many changed.pub async fn update_all(&self, db: &Db, sets: Vec<(&'static str, Param)>) -> Result<usize>ocre::Query::delete_all(fn): Deletes every matching row (Rails’delete_all) and returns how many were deleted.pub async fn delete_all(&self, db: &Db) -> Result<usize>- Implements:
Clone,Debug
ocre::RemoteIp(struct): Extractor for the client’s IP address, from Cloudflare’sCF-Connecting-IPheader.pub struct RemoteIp(pub Option<IpAddr>)- Implements:
Clone,Copy,Debug,Eq,FromRequestParts,PartialEq
- Implements:
ocre::RequestId(struct): Extractor for an identifier of the request, to correlate log lines and error reports.pub struct RequestId(pub String)- Implements:
Clone,Debug,Eq,FromRequestParts,PartialEq
- Implements:
ocre::Session(struct): The current request’s session, stored in an encrypted cookie, as an extractor.pub struct Session(/* private fields */)ocre::Session::expire_in(fn): Makes the session expiresecondsfrom now; the cookie still ends with the browser session.pub fn expire_in(&self, seconds: i64) -> Result<()>ocre::Session::remember_for(fn): Keeps the session forseconds, across browser restarts (“remember me”).pub fn remember_for(&self, seconds: i64) -> Result<()>ocre::Session::expires_at(fn): When the session expires, in Unix seconds, ifexpire_inorremember_forset it.pub fn expires_at(&self) -> Result<Option<i64>>ocre::Session::get(fn): Returns the value stored underkey, orNoneif absent or not deserializable asT.pub fn get<T: DeserializeOwned>(&self, key: &str) -> Result<Option<T>>ocre::Session::insert(fn): Storesvalueunderkey, replacing any previous value.pub fn insert(&self, key: &str, value: impl Serialize) -> Result<()>ocre::Session::remove(fn): Removeskeyand returns whether it was there.pub fn remove(&self, key: &str) -> Result<bool>ocre::Session::clear(fn): Empties the session (sign out); flash messages set during this request are kept.pub fn clear(&self) -> Result<()>ocre::Session::flash(fn): Storesmessageunderkindto show on the next request, usually after a redirect.pub fn flash(&self, kind: &str, message: impl Into<String>) -> Result<()>ocre::Session::flashes(fn): Returns the flash messages set by the previous request and removes them from the session.pub fn flashes(&self) -> Result<Flash>ocre::Session::keep_flash(fn): Keepsflashfor the next request too (Rails’flash.keep), e.g. when a page read the messages but redirects again before showing them.pub fn keep_flash(&self, flash: &Flash) -> Result<()>- Implements:
Clone,FromRequestParts
ocre::Statement(struct): One SQL statement with its parameters, forDb::batch.pub struct Statementocre::Statement::sql(field): SQL text with?1, ?2...placeholders.pub sql: Stringocre::Statement::params(field): Values for the placeholders, in order (build withparams!).pub params: Vec<Param>ocre::Statement::new(fn): Pairssqlwith itsparams.pub fn new(sql: impl Into<String>, params: Vec<Param>) -> Self- Implements:
Clone,Debug,PartialEq
ocre::Validator(struct): Collects field errors with Rails-style messages;finishfails with all of them.pub struct Validatorocre::Validator::file_content(fn): Checks that an upload’s bytes match its declared content type (Active Storage’s content-type identification).pub fn file_content(&mut self, field: &str, upload: &Upload) -> &mut Selfocre::Validator::file(fn): Checks an uploaded file againstrules: its size and its content type.pub fn file(&mut self, field: &str, upload: &Upload, rules: &Rules) -> &mut Selfocre::Validator::new(fn): Creates a validator with no errors.pub fn new() -> Selfocre::Validator::check(fn): Addsmessageforfieldwhenfailedis true: the building block for custom rules.pub fn check(&mut self, field: &str, failed: bool, message: impl Into<String>) -> &mut Selfocre::Validator::required(fn): Checks thatvalueis not empty after trimming whitespace (“can’t be blank”).pub fn required(&mut self, field: &str, value: &str) -> &mut Selfocre::Validator::max_length(fn): Checks thatvaluehas at mostmaxcharacters (Unicode scalar values, not bytes).pub fn max_length(&mut self, field: &str, value: &str, max: usize) -> &mut Selfocre::Validator::min_length(fn): Checks thatvaluehas at leastmincharacters (Unicode scalar values, not bytes).pub fn min_length(&mut self, field: &str, value: &str, min: usize) -> &mut Selfocre::Validator::range(fn): Checks thatvalueis withinrange, bounds included.pub fn range<T: PartialOrd + fmt::Display>(&mut self, field: &str, value: T, range: RangeInclusive<T>) -> &mut Selfocre::Validator::safe_integer(fn): Checks thatvalueis an integer D1 can store and return exactly (±2^53 - 1).pub fn safe_integer(&mut self, field: &str, value: i64) -> &mut Selfocre::Validator::inclusion(fn): Checks thatvalueis one ofallowed(“is not included in the list”).pub fn inclusion(&mut self, field: &str, value: &str, allowed: &[&str]) -> &mut Selfocre::Validator::exclusion(fn): Checks thatvalueis not one offorbidden(“is reserved”), like Rails’exclusion.pub fn exclusion(&mut self, field: &str, value: &str, forbidden: &[&str]) -> &mut Selfocre::Validator::length(fn): Checks thatvaluehas exactlylengthcharacters (Unicode scalar values): “is the wrong length (should be N characters)”.pub fn length(&mut self, field: &str, value: &str, length: usize) -> &mut Selfocre::Validator::greater_than(fn): Checks thatvalue > than(“must be greater than N”), like Rails’comparison.pub fn greater_than<T: PartialOrd + fmt::Display>(&mut self, field: &str, value: T, than: T) -> &mut Selfocre::Validator::greater_than_or_equal_to(fn): Checks thatvalue >= min(“must be greater than or equal to N”).pub fn greater_than_or_equal_to<T: PartialOrd + fmt::Display>(&mut self, field: &str, value: T, min: T) -> &mut Selfocre::Validator::less_than(fn): Checks thatvalue < than(“must be less than N”).pub fn less_than<T: PartialOrd + fmt::Display>(&mut self, field: &str, value: T, than: T) -> &mut Selfocre::Validator::less_than_or_equal_to(fn): Checks thatvalue <= max(“must be less than or equal to N”).pub fn less_than_or_equal_to<T: PartialOrd + fmt::Display>(&mut self, field: &str, value: T, max: T) -> &mut Selfocre::Validator::other_than(fn): Checks thatvalue != other(“must be other than N”).pub fn other_than<T: PartialEq + fmt::Display>(&mut self, field: &str, value: T, other: T) -> &mut Selfocre::Validator::confirmation(fn): Checks thatconfirmationequalsvalue, like Rails’confirmation: the error goes on<field>_confirmation(“doesn’t match Password”).pub fn confirmation(&mut self, field: &str, value: &str, confirmation: &str) -> &mut Selfocre::Validator::acceptance(fn): Checks that a checkbox was ticked (“must be accepted”), like Rails’acceptance.pub fn acceptance(&mut self, field: &str, accepted: bool) -> &mut Selfocre::Validator::absence(fn): Checks thatvalueis blank: empty or only whitespace (“must be blank”), like Rails’absence.pub fn absence(&mut self, field: &str, value: &str) -> &mut Selfocre::Validator::format(fn): Checks that every character ofvaluepassesallowed(“is invalid”): Rails’format, without regular expressions (no regex engine in the WebAssembly binary).pub fn format(&mut self, field: &str, value: &str, allowed: impl Fn(char) -> bool) -> &mut Selfocre::Validator::message(fn): Replaces the message of the check just before, if it failed (Rails’message:option).pub fn message(&mut self, message: impl Into<String>) -> &mut Selfocre::Validator::errors(fn): The errors collected so far, in the order the checks ran (Rails’errors).pub fn errors(&self) -> &[FieldError]ocre::Validator::email(fn): Checks thatvaluelooks like an e-mail address (“is invalid”).pub fn email(&mut self, field: &str, value: &str) -> &mut Selfocre::Validator::number(fn): Parses a required number typed as text (HTML forms), adding “is not a number” when it does not parse.pub fn number<T: FromStr>(&mut self, field: &str, text: &str) -> Option<T>ocre::Validator::optional_number(fn): Parses an optional number typed as text: blank text isNonewithout an error.pub fn optional_number<T: FromStr>(&mut self, field: &str, text: &str) -> Option<T>ocre::Validator::one_of(fn): Parses form text into one of an enum’s values, likenumber:Noneplus “is not included in the list” whenT::from_strrefuses it.pub fn one_of<T: FromStr>(&mut self, field: &str, text: &str) -> Option<T>ocre::Validator::optional_one_of(fn): Likeone_offor an optional field: blank text isNonewithout error.pub fn optional_one_of<T: FromStr>(&mut self, field: &str, text: &str) -> Option<T>ocre::Validator::json(fn): Parses a required JSON value typed as text (a<textarea>), adding “is not valid JSON” when it does not parse.pub fn json(&mut self, field: &str, text: &str) -> Option<serde_json::Value>ocre::Validator::optional_json(fn): Parses an optional JSON value typed as text: blank text isNonewithout an error.pub fn optional_json(&mut self, field: &str, text: &str) -> Option<serde_json::Value>ocre::Validator::date(fn): Checks thatvalueis a real calendar date writtenYYYY-MM-DD(“is not a valid date”).pub fn date(&mut self, field: &str, value: &str) -> &mut Selfocre::Validator::datetime(fn): Checks thatvalueisYYYY-MM-DD HH:MM[:SS], with a space orT(HTMLdatetime-local).pub fn datetime(&mut self, field: &str, value: &str) -> &mut Selfocre::Validator::time(fn): Checks thatvalueis a time of day writtenHH:MMorHH:MM:SS(HTML<input type="time">).pub fn time(&mut self, field: &str, value: &str) -> &mut Selfocre::Validator::uuid(fn): Checks thatvalueis a UUID in its hyphenated form, any case (“is not a valid UUID”).pub fn uuid(&mut self, field: &str, value: &str) -> &mut Selfocre::Validator::decimal(fn): Checks thatvalueis an exact decimal number such as-12.50(“is not a decimal number”).pub fn decimal(&mut self, field: &str, value: &str) -> &mut Selfocre::Validator::merge(fn): Adds the errors collected byother, e.g. a model’svalidate()after parsing a form.pub fn merge(&mut self, mut other: Validator) -> &mut Selfocre::Validator::is_valid(fn): Whether no error has been collected so far.pub fn is_valid(&self) -> boolocre::Validator::finish(fn): ReturnsOk(())when every check passed, and takes the collected errors otherwise.pub fn finish(&mut self) -> Result<(), Error>- Implements:
Debug,Default
ocre::Direction(enum): Sort direction forQuery::order_by, read from a query string asascordesc.pub enum Directionocre::Direction::Asc(variant): Smallest first (ASC).Ascocre::Direction::Desc(variant): Largest first (DESC).Descocre::Direction::as_sql(fn):ASCorDESC.pub fn as_sql(self) -> &'static str- Implements:
Clone,Copy,Debug,Default,Deserialize,Eq,PartialEq,Serialize
ocre::Error(enum): Handler error: an HTTP status plus, for client errors, a message the user may see.pub enum Errorocre::Error::NotFound(variant): 404 Not Found: the record or route does not exist.NotFoundocre::Error::BadRequest(variant): 400 Bad Request, with a message shown to the user.BadRequest(String)ocre::Error::Unauthorized(variant): 401 Unauthorized: missing or invalid credentials (password, session, token).Unauthorizedocre::Error::Forbidden(variant): 403 Forbidden: signed in, but not allowed to do this.Forbiddenocre::Error::Invalid(variant): 422 Unprocessable Entity: failed validations, one entry per field error.Invalid(Vec<FieldError>)ocre::Error::Conflict(variant): 409 Conflict: the record changed since it was read (optimistic locking with alock_versioncolumn), or a unique key already exists; the message is shown to the user.Conflict(String)ocre::Error::PayloadTooLarge(variant): 413 Payload Too Large: the request body is over a limit, with a message shown to the user.PayloadTooLarge(String)ocre::Error::TooManyRequests(variant): 429 Too Many Requests: a rate limit was hit.TooManyRequestsocre::Error::Internal(variant): 500 Internal Server Error; the message goes to the Worker logs only.Internal(String)ocre::Error::bad_request(fn): Builds a 400Error::BadRequestwhose message is shown to the user.pub fn bad_request(message: impl Into<String>) -> Selfocre::Error::internal(fn): Builds a 500Error::Internalwhose message is logged, never shown to the user.pub fn internal(message: impl Into<String>) -> Selfocre::Error::is_taken(fn): Whether the error says a unique value is already used: a “has already been taken” validation error (generated models check unique fields before writing), D1’sUNIQUE constraint failed(two requests raced past the check), or aConflict.pub fn is_taken(&self) -> bool- Implements:
Debug,Display,Error,From,IntoResponse
ocre::Format(enum): Response format a client asks for in itsAcceptheader, for actions that answer HTML or JSON (Rails’respond_to).pub enum Formatocre::Format::Html(variant):text/html: a page.Htmlocre::Format::Json(variant):application/json.Jsonocre::Format::Xml(variant):application/xmlortext/xml, e.g. an RSS or Atom feed.Xmlocre::Format::Text(variant):text/plain.Textocre::Format::Markdown(variant):text/markdown, e.g. for LLM clients (Rails’format.md); answer withMarkdown.Markdownocre::Format::Other(variant): Only types Ocre does not know, e.g.application/pdf.Otherocre::Format::from_headers(fn): Reads theAcceptheader; seeFormatfor the rules.pub fn from_headers(headers: &HeaderMap) -> Self- Implements:
Clone,Copy,Debug,Eq,FromRequestParts,PartialEq
ocre::IntoParam(trait): Types that can be bound as D1 query parameters.pub trait IntoParamocre::IntoParam::into_param(fn): Converts the value into a bound parameter.fn into_param(self) -> Param
ocre::OptionExt(trait): Extension forOption:option.or_404()?turns a missing record into a 404 response.pub trait OptionExt<T>ocre::OptionExt::or_404(fn): The value, orError::NotFound(404) whenNone.fn or_404(self) -> Result<T>
ocre::ApiResult(type):Resultfor JSON handlers: errors becomeApiErrorJSON responses.pub type ApiResult<T> = Result<T, ApiError>ocre::Result(type):ResultwithErroras the default error type, returned by Ocre APIs and handlers.pub type Result<T, E = Error> = std::result::Result<T, E>ocre::ALLOWED_HOSTS(const): Name of the Worker variable listing the host names the app answers to (Rails’config.hosts).pub const ALLOWED_HOSTS: &str = "ALLOWED_HOSTS"ocre::ALLOWED_ORIGINS(const): Name of the Worker variable listing extra origins that may call the app from a browser.pub const ALLOWED_ORIGINS: &str = "ALLOWED_ORIGINS"ocre::MAX_SAFE_INTEGER(const): Largest integer a JavaScript number (and so D1) represents exactly: 2^53 - 1.pub const MAX_SAFE_INTEGER: i64 = (1 <<53) - 1ocre::SECRET_KEY_BASE(const): Name of the Worker secret the session encryption key is derived from:SECRET_KEY_BASE.pub const SECRET_KEY_BASE: &str = "SECRET_KEY_BASE"ocre::SECRET_KEY_BASE_PREVIOUS(const): Name of the Worker secret listing the previousSECRET_KEY_BASEvalues, during a rotation.pub const SECRET_KEY_BASE_PREVIOUS: &str = "SECRET_KEY_BASE_PREVIOUS"ocre::SESSION_COOKIE(const): Name of the session cookie:_ocre_session.pub const SESSION_COOKIE: &str = "_ocre_session"
ocre::bulk
ocre::bulk::insert(fn):INSERT INTO table (columns) SELECT ... FROM json_each(?1): every row in one statement.pub fn insert<T: Serialize>(table: &str, columns: &[&str], rows: &[T]) -> Result<Statement>ocre::bulk::update(fn):UPDATE table SET ... FROM json_each(?1) WHERE table.key = ...: a value per row for many rows in one statement.pub fn update<T: Serialize>(table: &str, key: &str, columns: &[&str], rows: &[T], touch: bool) -> Result<Statement>ocre::bulk::upsert(fn):INSERT ... ON CONFLICT (key) DO UPDATE SET ...: inserts the rows, and updates the listed columns of those whosekeyalready exists (Rails’upsert_all).pub fn upsert<T: Serialize>(table: &str, key: &str, columns: &[&str], rows: &[T]) -> Result<Statement>
ocre::cache
ocre::cache::clear(fn): Deletes up tolimitcached values whose key starts withprefix(Rails’Rails.cache.clear, bounded):""for everything,"views/"for fragments,"posts/"for one family of keys.pub fn clear<'a>(ctx: &Ctx, prefix: &'a str, limit: usize) -> impl Future<Output = Result<crate::cache::Cleared>> + Send + use<'a>ocre::cache::delete(fn): Removeskey, e.g. after the data behind it changed (Rails’Rails.cache.delete).pub fn delete<'a>(ctx: &Ctx, key: &'a str) -> impl Future<Output = Result<()>> + Send + use<'a>ocre::cache::fetch(fn): Read-through cache, like Rails’Rails.cache.fetch: the value underkeyin KV, or else the result ofcompute.pub fn fetch<'a, T, F, Fut>(ctx: &Ctx, key: &'a str, ttl: Duration, compute: F) -> impl Future<Output = Result<T>> + Send + use<'a, T, F, Fut> where T: Serialize + DeserializeOwned, F: FnOnce() -> Fut, Fut: Future<Output = Result<T>>ocre::cache::fragment(fn, featurehtml): Fragment caching, like Rails’<% cache post do %>: the HTML stored underkey, or else the templatebuildreturns, rendered and stored.pub fn fragment<T, F>(ctx: &Ctx, key: &str, ttl: Duration, build: F) -> impl Future<Output = Result<Fragment>> + Send + use<T, F> where T: askama::Template, F: FnOnce() -> Tocre::cache::fragments(fn, featurehtml): Collection caching, like Rails’render collection:, cached: true: oneFragmentper item, read from KV in bulk.pub fn fragments<'a, I, T, K, F>(ctx: &Ctx, items: &'a [I], ttl: Duration, key: K, build: F) -> impl Future<Output = Result<Vec<Fragment>>> + Send + use<'a, I, T, K, F> where T: askama::Template, K: Fn(&I) -> String, F: Fn(&'a I) -> Tocre::cache::key(fn): Builds a cache key from its parts joined by/, like Rails’cache_key_with_version.pub fn key(parts: &[&(dyn fmt::Display + Sync)]) -> Stringocre::cache::read(fn): The value underkey, orNonewhen it is absent, expired, unreadable asT, or when KV fails.pub fn read<'a, T: DeserializeOwned>(ctx: &Ctx, key: &'a str) -> impl Future<Output = Result<Option<T>>> + Send + use<'a, T>ocre::cache::write(fn): Storesvalueas JSON underkeyforttl, replacing any previous value.pub fn write<'a, T: Serialize + ?Sized>(ctx: &Ctx, key: &'a str, value: &T, ttl: Duration) -> impl Future<Output = Result<()>> + Send + use<'a, T>ocre::cache::CacheControl(struct): ACache-Controlresponse header, built from one of four policies.pub struct CacheControlocre::cache::CacheControl::no_store(fn): Ano-storepolicy: never keep a copy (pages with secrets, one-time tokens).pub fn no_store() -> Selfocre::cache::CacheControl::no_cache(fn): Aprivate, no-cachepolicy: the browser keeps a copy but asks every time.pub fn no_cache() -> Selfocre::cache::CacheControl::private(fn): Aprivate, max-age=Npolicy: the browser reuses its copy formax_agewithout asking.pub fn private(max_age: Duration) -> Selfocre::cache::CacheControl::public(fn): Apublic, max-age=Npolicy: browsers and Cloudflare may reuse it for every visitor.pub fn public(max_age: Duration) -> Selfocre::cache::CacheControl::stale_while_revalidate(fn): Addsstale-while-revalidate, serving the old copy for up towindowwhile fetching a new one.pub fn stale_while_revalidate(self, window: Duration) -> Self- Implements:
Clone,Copy,Debug,Display,Eq,IntoResponseParts,PartialEq
ocre::cache::Cleared(struct): Whatcleardeleted.pub struct Clearedocre::cache::Cleared::deleted(field): How many values were deleted.pub deleted: usizeocre::cache::Cleared::more(field): Whether keys with the prefix remain.pub more: bool- Implements:
Clone,Copy,Debug,Default,Eq,PartialEq
ocre::cache::Conditional(struct): Extractor for the request’sIf-None-Match, to answer304 Not Modifiedwithout rendering.pub struct Conditionalocre::cache::Conditional::is_fresh(fn): Whether the client already has the versionetag.pub fn is_fresh(&self, etag: &ETag) -> boolocre::cache::Conditional::fresh_when(fn): Answers304 Not Modifiedwhen the client’s copy is current, or else renders the page.pub fn fresh_when<R: IntoResponse>(&self, etag: ETag, cache_control: CacheControl, render: impl FnOnce() -> Result<R>) -> Result<Response>- Implements:
Clone,Debug,Default,FromRequestParts
ocre::cache::ETag(struct): An entity tag naming the version of what a page shows: weak (W/"<hash>", the default) or strong ("<hash>").pub struct ETag(/* private fields */)ocre::cache::ETag::new(fn): A tag for a version string you build, e.g.format!("{}-{}", post.id, post.updated_at).pub fn new(version: impl AsRef<[u8]>) -> Selfocre::cache::ETag::strong(fn): A strong tag ("<hash>", Rails’strong_etag:) for a version string you build.pub fn strong(version: impl AsRef<[u8]>) -> Selfocre::cache::ETag::is_strong(fn): Whether the tag is strong (built withstrong).pub fn is_strong(&self) -> boolocre::cache::ETag::of(fn): A tag for any serializable data, hashed as its JSON:ETag::of(&(&posts, i18n.locale()))?.pub fn of<T: Serialize + ?Sized>(data: &T) -> Result<Self>ocre::cache::ETag::as_str(fn): The header value,W/"<32 hex characters>"(weak) or"<32 hex characters>"(strong).pub fn as_str(&self) -> &str- Implements:
Clone,Debug,Eq,IntoResponseParts,PartialEq
ocre::cache::Fragment(struct): A cached piece of HTML, fromfragmentorfragments.pub struct Fragment(/* private fields */)ocre::cache::Fragment::as_str(fn): The HTML.pub fn as_str(&self) -> &strocre::cache::Fragment::into_string(fn): The HTML as aString, e.g. for arealtimebroadcast.pub fn into_string(self) -> String- Implements:
Clone,Debug,Display,Eq,HtmlSafe,PartialEq
ocre::cache::CACHE_BINDING(const): Name of the KV namespace binding holding cached values:CACHE.pub const CACHE_BINDING: &str = "CACHE"ocre::cache::FRAGMENT_PREFIX(const): Prefix of the KV keys holdingfragments:views/, as in Rails.pub const FRAGMENT_PREFIX: &str = "views/"ocre::cache::LOG_PREFIX(const): Prefix of every line Ocre logs about the cache:[ocre cache].pub const LOG_PREFIX: &str = "[ocre cache]"ocre::cache::MIN_TTL(const): Shortest TTL KV accepts (expirationTtl): 60 seconds.pub const MIN_TTL: Duration = Duration::from_secs(60)ocre::cache::STORE_VAR(const): Name of the Worker variable choosing the cache store:CACHE_STORE.pub const STORE_VAR: &str = "CACHE_STORE"
ocre::config
ocre::config::from_vars(fn): ReadsTfrom the given variables: whatCtx::configdoes with the Worker’s environment.pub fn from_vars<'a, T: DeserializeOwned>(vars: impl IntoIterator<Item = (&'a str, &'a str)>) -> crate::Result<T>ocre::config::Environment(enum): Where the Worker runs, from its build profile (Rails’Rails.env, Loco’s environment).pub enum Environmentocre::config::Environment::Development(variant): Debug build:ocre dev,cargo test,ocre test.Developmentocre::config::Environment::Production(variant): Release build:ocre deploy.Productionocre::config::Environment::current(fn): The environment of this build.pub fn current() -> Selfocre::config::Environment::as_str(fn):developmentorproduction, as sent to error reporters.pub fn as_str(self) -> &'static strocre::config::Environment::is_development(fn): Whether this isDevelopment.pub fn is_development(self) -> bool- Implements:
Clone,Copy,Debug,Eq,PartialEq
ocre::encryption
ocre::encryption::install(fn): Makesencryptorthe oneEncryptedandDeterministicuse.pub fn install(encryptor: Encryptor)ocre::encryption::installed(fn): The installed encryptor.pub fn installed() -> Result<Encryptor>ocre::encryption::is_encrypted(fn): Whethertextlooks like an encrypted value (starts withv1:).pub fn is_encrypted(text: &str) -> boolocre::encryption::Deterministic(struct): A column encrypted deterministically: equal values give equal stored texts, soquery().eq("email", Deterministic::from(email))finds the row and aUNIQUEindex works.pub struct Deterministic(pub String)ocre::encryption::Deterministic::as_str(fn): The plain value.encrypted_type!(Deterministic, encrypt_deterministic)- Implements:
Clone,Debug,Deserialize,Display,Eq,From,IntoParam,PartialEq,Serialize
ocre::encryption::Encrypted(struct): A column encrypted with a random nonce: reads decrypt, writes encrypt.pub struct Encrypted(pub String)ocre::encryption::Encrypted::as_str(fn): The plain value.encrypted_type!(Encrypted, encrypt)- Implements:
Clone,Debug,Deserialize,Display,Eq,From,IntoParam,PartialEq,Serialize
ocre::encryption::Encryptor(struct): Encrypts and decrypts column values with keys derived fromSECRET_KEY_BASE.pub struct Encryptorocre::encryption::Encryptor::new(fn): Derives the keys from the current secret and the previous ones (newest first).pub fn new(secret: &str, previous: &[&str]) -> Result<Self>ocre::encryption::Encryptor::encrypt(fn): Encryptsplaintextwith a random nonce:v1:plus URL-safe base64.pub fn encrypt(&self, plaintext: &str) -> Stringocre::encryption::Encryptor::encrypt_deterministic(fn): Encryptsplaintextso that equal values give equal texts (seeDeterministic).pub fn encrypt_deterministic(&self, plaintext: &str) -> Stringocre::encryption::Encryptor::deterministic_candidates(fn): The deterministic texts ofplaintextunder every key, current first: look rows up withQuery::is_induring a key rotation.pub fn deterministic_candidates(&self, plaintext: &str) -> Vec<String>ocre::encryption::Encryptor::decrypt(fn): Decrypts a value fromencryptorencrypt_deterministic, with the current key or a previous one.pub fn decrypt(&self, ciphertext: &str) -> Result<String>ocre::encryption::Encryptor::decrypt_or_plaintext(fn): Likedecrypt, but a value without thev1:prefix is returned as is: read a column while a data migration encrypts its existing rows (Rails’support_unencrypted_data).pub fn decrypt_or_plaintext(&self, text: &str) -> Result<String>- Implements:
Clone,Debug
ocre::errors
ocre::errors::subscribe(fn): Registers a subscriber for every report of this Worker instance (Rails’Rails.error.subscribe).pub fn subscribe(subscriber: impl Subscriber + 'static)ocre::errors::Delivery(struct): An HTTPPOSTaSubscriberasks Ocre to send for a report.pub struct Deliveryocre::errors::Delivery::url(field): Where toPOST.pub url: Stringocre::errors::Delivery::headers(field): Request headers, e.g. an API key.pub headers: Vec<(String, String)>ocre::errors::Delivery::body(field): The request body.pub body: String- Implements:
Clone,Debug,PartialEq
ocre::errors::Options(struct): Options of one report (Rails’handled:,severity:,context:,source:).pub struct Optionsocre::errors::Options::new(fn): The defaults: handled, warning, no context, sourceapplication.pub fn new() -> Selfocre::errors::Options::handled(fn): Whether the app recovered from the error (falsefor errors that failed the request or job).pub fn handled(mut self, handled: bool) -> Selfocre::errors::Options::severity(fn): The report’sSeverity.pub fn severity(mut self, severity: Severity) -> Selfocre::errors::Options::context(fn): Adds a context entry, merged over the request’sReporter::set_contextentries.pub fn context(mut self, key: &str, value: impl Serialize) -> Selfocre::errors::Options::source(fn): Where the error comes from, e.g.billing(Rails’source:).pub fn source(mut self, source: &str) -> Selfocre::errors::Options::except(fn): Does not send this report to the subscriber namedname(Rails’Rails.error.disable).pub fn except(mut self, subscriber: &'static str) -> Self- Implements:
Clone,Debug,Default
ocre::errors::Report(struct): One reported error, as subscribers receive it.pub struct Reportocre::errors::Report::class(field): The error’s type, e.g.ocre::error::Error(Sentry’s exception type).pub class: Stringocre::errors::Report::message(field): The error’s text (Display).pub message: Stringocre::errors::Report::handled(field): Whether the app recovered from it.pub handled: boolocre::errors::Report::severity(field): How bad it is.pub severity: Severityocre::errors::Report::context(field): The request’s context, then the report’s own entries.pub context: Map<String, Value>ocre::errors::Report::source(field): Where it comes from:application,ocre.request,ocre.job…pub source: Stringocre::errors::Report::timestamp(field): When it was reported, in Unix seconds.pub timestamp: i64ocre::errors::Report::environment(field): Development or production, from the build profile.pub environment: Environment- Implements:
Clone,Debug,PartialEq
ocre::errors::Reporter(struct): The error reporter of one request, job batch or cron run:Ctx::errors.pub struct Reporterocre::errors::Reporter::set_context(fn): Adds context to every later report of this request or job (Rails’Rails.error.set_context).pub fn set_context(&self, key: &str, value: impl Serialize)ocre::errors::Reporter::report(fn): Reports an error (Rails’Rails.error.report): logs it and queues it for the subscribers.pub fn report<E: Display + ?Sized>(&self, error: &E, options: Options)ocre::errors::Reporter::handle(fn): Reports the error ofresult, if any, as handled, and returns its value (Rails’Rails.error.handle).pub fn handle<T, E: Display>(&self, result: Result<T, E>) -> Option<T>ocre::errors::Reporter::record(fn): Reports the error ofresult, if any, as unhandled, and returnsresultunchanged (Rails’Rails.error.record).pub fn record<T, E: Display>(&self, result: Result<T, E>) -> Result<T, E>ocre::errors::Reporter::unexpected(fn): Reports something that should never happen (Rails’Rails.error.unexpected).pub fn unexpected(&self, message: impl Display)ocre::errors::Reporter::take(fn): Takes the reports made so far, for the subscribers (or a test).pub fn take(&self) -> Vec<Report>- Implements:
Clone,Debug,Default
ocre::errors::Sentry(struct): Sends reports to Sentry or a Sentry-compatible service, as envelopes (the Sentry ingestion protocol).pub struct Sentry- Implements:
Clone,Copy,Debug,Subscriber
- Implements:
ocre::errors::Severity(enum): How bad a report is (Rails’severity:).pub enum Severityocre::errors::Severity::Error(variant): A failure: the default ofReporter::recordand of Ocre’s own reports.Errorocre::errors::Severity::Warning(variant): Handled, worth looking at: the default ofReporter::reportandReporter::handle.Warningocre::errors::Severity::Info(variant): For information.Infoocre::errors::Severity::as_str(fn):error,warningorinfo, as Sentry names levels.pub fn as_str(self) -> &'static str- Implements:
Clone,Copy,Debug,Eq,PartialEq
ocre::errors::Subscriber(trait): An error-reporting service (Rails’ error subscribers): turns aReportinto the request to send.pub trait Subscriber: Send + Syncocre::errors::Subscriber::name(fn): A short name, forOptions::exceptand failure logs:sentry.fn name(&self) -> &'static strocre::errors::Subscriber::deliver(fn): The request to send forreport, if any.fn deliver(&self, report: &Report, vars: &dyn Fn(&str) -> Option<String>) -> Option<Delivery>
ocre::errors::SENTRY_DSN(const): Worker secret holding the Sentry DSN:https://<key>@<host>/<project id>.pub const SENTRY_DSN: &str = "SENTRY_DSN"
ocre::events
ocre::events::subscribe(fn): Registers a subscriber for every event of this Worker instance (Rails’Rails.event.subscribe).pub fn subscribe(subscriber: impl Subscriber + 'static)ocre::events::Delivery(struct): An HTTPPOSTaSubscriberasks Ocre to send for a report.pub struct Deliveryocre::events::Delivery::url(field): Where toPOST.pub url: Stringocre::events::Delivery::headers(field): Request headers, e.g. an API key.pub headers: Vec<(String, String)>ocre::events::Delivery::body(field): The request body.pub body: String- Implements:
Clone,Debug,PartialEq
ocre::events::Event(struct): A structured event, fromEvents::notify.pub struct Eventocre::events::Event::name(field): What happened, e.g.order.placed.pub name: Stringocre::events::Event::payload(field): Its data; a payload that is not a JSON object is kept undervalue.pub payload: Map<String, Value>ocre::events::Event::tags(field): Tags of theEventsthat notified it (Events::tagged).pub tags: Map<String, Value>ocre::events::Event::context(field): The request’s or job’s context (Events::set_context).pub context: Map<String, Value>ocre::events::Event::timestamp(field): When it happened, in Unix seconds.pub timestamp: i64- Implements:
Clone,Debug,PartialEq
ocre::events::Events(struct): The event notifier of one request, job batch or cron run:Ctx::events.pub struct Eventsocre::events::Events::notify(fn): Records an event (Rails’Rails.event.notify): logs it and queues it for the subscribers.pub fn notify(&self, name: &str, payload: impl Serialize)ocre::events::Events::tagged(fn): This notifier with a tag added to its events (Rails’Rails.event.tagged).pub fn tagged(&self, key: &str, value: impl Serialize) -> Selfocre::events::Events::set_context(fn): Adds context to every later event of this request or job (Rails’Rails.event.set_context).pub fn set_context(&self, key: &str, value: impl Serialize)ocre::events::Events::take(fn): Takes the events not yet sent to the subscribers, oldest first.pub fn take(&self) -> Vec<Event>- Implements:
Clone,Debug,Default
ocre::events::Subscriber(trait): A destination for events (Rails’ event subscribers): turns anEventinto the request to send.pub trait Subscriber: Send + Syncocre::events::Subscriber::name(fn): A short name, for failure logs:analytics.fn name(&self) -> &'static strocre::events::Subscriber::emit(fn): The request to send forevent, if any.fn emit(&self, event: &Event, vars: &dyn Fn(&str) -> Option<String>) -> Option<Delivery>
ocre::filters (feature html)
ocre::filters::distance_of_time_in_words(struct) ``ocre::filters::distance_of_time_in_words::execute(fn)(value: impl Display, _: &dyn Values, to: T)- Implements:
Default
ocre::filters::excerpt(struct) ``ocre::filters::excerpt::execute(fn)(value: impl Display, _: &dyn Values, phrase: &str, radius: usize)- Implements:
Default
ocre::filters::highlight(struct) ``ocre::filters::highlight::execute(fn)(value: impl Display, _: &dyn Values, phrase: &str)- Implements:
Default
ocre::filters::number_to_currency(struct) ``ocre::filters::number_to_currency::execute(fn)(value: impl Display, _: &dyn Values, unit: &str)- Implements:
Default
ocre::filters::number_to_human(struct) ``ocre::filters::number_to_human::execute(fn)(value: impl Display, _: &dyn Values)- Implements:
Default
ocre::filters::number_to_human_size(struct) ``ocre::filters::number_to_human_size::execute(fn)(value: impl Display, _: &dyn Values)- Implements:
Default
ocre::filters::number_to_percentage(struct) ``ocre::filters::number_to_percentage::execute(fn)(value: impl Display, _: &dyn Values, precision: usize)- Implements:
Default
ocre::filters::number_with_delimiter(struct) ``ocre::filters::number_with_delimiter::execute(fn)(value: impl Display, _: &dyn Values)- Implements:
Default
ocre::filters::number_with_precision(struct) ``ocre::filters::number_with_precision::execute(fn)(value: impl Display, _: &dyn Values, precision: usize)- Implements:
Default
ocre::filters::plain_text(struct) ``ocre::filters::plain_text::execute(fn)(value: impl Display, _: &dyn Values)- Implements:
Default
ocre::filters::rich_text(struct) ``ocre::filters::rich_text::execute(fn)(value: impl Display, _: &dyn Values)- Implements:
Default
ocre::filters::strftime(struct) ``ocre::filters::strftime::execute(fn)(value: impl Display, _: &dyn Values, format: &str)- Implements:
Default
ocre::filters::time_ago_in_words(struct) ``ocre::filters::time_ago_in_words::execute(fn)(value: impl Display, _: &dyn Values)- Implements:
Default
ocre::filters::word_wrap(struct) ``ocre::filters::word_wrap::execute(fn)(value: impl Display, _: &dyn Values, width: usize)- Implements:
Default
ocre::graphql (feature graphql)
ocre::graphql::async_graphql(re-export)pub use async_graphqlocre::graphql::graphiql(fn): Renders GraphiQL, the in-browser query editor, pointed at/graphql.pub fn graphiql() -> Html<String>ocre::graphql::respond(fn): Executes aPOST /graphqlJSON body againstschemaand returns the JSON response.pub async fn respond<Q, M, S>(schema: &Schema<Q, M, S>, body: &[u8], data: impl Any + Send + Sync) -> Response where Q: ObjectType + 'static, M: ObjectType + 'static, S: SubscriptionType + 'staticocre::graphql::routes(fn): Returns a router serving GraphiQL onGET /graphqland queries onPOST /graphql.pub fn routes<Q, M, S>(schema: fn() -> &'static Schema<Q, M, S>) -> Router<Ctx> where Q: ObjectType + 'static, M: ObjectType + 'static, S: SubscriptionType + 'static
ocre::helpers
ocre::helpers::class_names(fn): Space-separated class names whose condition is true (Rails’class_names/token_list).pub fn class_names(classes: &[(&str, bool)]) -> Stringocre::helpers::current_page(fn): Whetherurlnames the page being shown (Rails’current_page?), for “you are here” links.pub fn current_page(current: &str, url: &str) -> boolocre::helpers::distance_of_time_in_words(fn): The time between two times, in words:5 minutes,2 days(Rails’distance_of_time_in_words).pub fn distance_of_time_in_words(from: impl Display, to: impl Display) -> Stringocre::helpers::excerpt(fn): The first match ofphrase(case-insensitive) withradiuscharacters around it,...where cut (Rails’excerpt).pub fn excerpt(value: impl Display, phrase: &str, radius: usize) -> Stringocre::helpers::highlight(fn): The text, HTML-escaped, with each match ofphrase(case-insensitive) in<mark>(Rails’highlight).pub fn highlight(value: impl Display, phrase: &str) -> Stringocre::helpers::number_to_currency(fn): Two decimals, thousands grouped,unitfirst:1234.5with"$"becomes$1,234.50,-3becomes-$3.00(Rails’number_to_currency).pub fn number_to_currency(value: impl Display, unit: &str) -> Stringocre::helpers::number_to_human(fn): Three significant digits and a word, Thousand to Quadrillion:1234567becomes1.23 Million(Rails’number_to_human).pub fn number_to_human(value: impl Display) -> Stringocre::helpers::number_to_human_size(fn): A byte count in 1024 steps:1536becomes1.5 KB(Rails’number_to_human_size, asstorage::human_size).pub fn number_to_human_size(value: impl Display) -> Stringocre::helpers::number_to_percentage(fn): Rounds toprecisiondecimals and adds%:12.345with 1 becomes12.3%(Rails’number_to_percentage).pub fn number_to_percentage(value: impl Display, precision: usize) -> Stringocre::helpers::number_with_delimiter(fn): Groups the integer part by thousands:1234567.891becomes1,234,567.891(Rails’number_with_delimiter).pub fn number_with_delimiter(value: impl Display) -> Stringocre::helpers::number_with_precision(fn): Rounds toprecisiondecimals:3.14159with 2 becomes3.14(Rails’number_with_precision).pub fn number_with_precision(value: impl Display, precision: usize) -> Stringocre::helpers::progress_bar(fn): A progress bar with the element idid: a<progress>atpercent(clamped to 0-100) and alabel(escaped), as HTML.pub fn progress_bar(id: &str, percent: i64, label: &str) -> Stringocre::helpers::strftime(fn): Formats a time in UTC withstrftimedirectives:%b %-d, %YgivesSep 29, 2026.pub fn strftime(value: impl Display, format: &str) -> Stringocre::helpers::time_ago_in_words(fn): The time fromvaluetonow, in words:about 3 hours(Rails’time_ago_in_words).pub fn time_ago_in_words(value: impl Display) -> Stringocre::helpers::time_zone_options(fn): The<option>s of everyTIME_ZONESname,selectedmarked (Rails’time_zone_select): write them in a<select>, and store the IANA name the form sends.pub fn time_zone_options(selected: &str) -> Stringocre::helpers::word_wrap(fn): Breaks lines longer thanwidthcharacters at spaces (Rails’word_wrap).pub fn word_wrap(value: impl Display, width: usize) -> Stringocre::helpers::TIME_ZONES(const): IANA time zone names, as browsers list them (Intl.supportedValuesOf("timeZone")): whattime_zone_optionsoffers andocre time-zonesprints.pub const TIME_ZONES: &[&str] = &[ "UTC", "Africa/Abidjan", "Africa/Accra", "Africa/Addis_Ababa", "Africa/Algiers", "Africa/Asmera", "Africa/Bamako", "Africa/Bangui", "Africa/Banjul", "Africa/Bissau", "Africa/Blantyre", "Africa/Brazzaville", "Africa/Bujumbura", "Africa/Cairo", "Africa/Casablanca", "Africa/Ceuta", "Africa/Conakry", "Africa/Dakar", "Africa/Dar_es_Salaam", "Africa/Djibouti", "Africa/Douala", "Africa/El_Aaiun", "Africa/Freetown", "Africa/Gaborone", "Africa/Harare", "Africa/Johannesburg", "Africa/Juba", "Africa/Kampala", "Africa/Khartoum", "Africa/Kigali", "Africa/Kinshasa", "Africa/Lagos", "Africa/Libreville", "Africa/Lome", "Africa/Luanda", "Africa/Lubumbashi", "Africa/Lusaka", "Africa/Malabo", "Africa/Maputo", "Africa/Maseru", "Africa/Mbabane", "Africa/Mogadishu", "Africa/Monrovia", "Africa/Nairobi", "Africa/Ndjamena", "Africa/Niamey", "Africa/Nouakchott", "Africa/Ouagadougou", "Africa/Porto-Novo", "Africa/Sao_Tome", "Africa/Tripoli", "Africa/Tunis", "Africa/Windhoek", "America/Adak", "America/Anchorage", "America/Anguilla", "America/Antigua", "America/Araguaina", "America/Argentina/La_Rioja", "America/Argentina/Rio_Gallegos", "America/Argentina/Salta", "America/Argentina/San_Juan", "America/Argentina/San_Luis", "America/Argentina/Tucuman", "America/Argentina/Ushuaia", "America/Aruba", "America/Asuncion", "America/Bahia", "America/Bahia_Banderas", "America/Barbados", "America/Belem", "America/Belize", "America/Blanc-Sablon", "America/Boa_Vista", "America/Bogota", "America/Boise", "America/Buenos_Aires", "America/Cambridge_Bay", "America/Campo_Grande", "America/Cancun", "America/Caracas", "America/Catamarca", "America/Cayenne", "America/Cayman", "America/Chicago", "America/Chihuahua", "America/Ciudad_Juarez", "America/Coral_Harbour", "America/Cordoba", "America/Costa_Rica", "America/Coyhaique", "America/Creston", "America/Cuiaba", "America/Curacao", "America/Danmarkshavn", "America/Dawson", "America/Dawson_Creek", "America/Denver", "America/Detroit", "America/Dominica", "America/Edmonton", "America/Eirunepe", "America/El_Salvador", "America/Fort_Nelson", "America/Fortaleza", "America/Glace_Bay", "America/Godthab", "America/Goose_Bay", "America/Grand_Turk", "America/Grenada", "America/Guadeloupe", "America/Guatemala", "America/Guayaquil", "America/Guyana", "America/Halifax", "America/Havana", "America/Hermosillo", "America/Indiana/Knox", "America/Indiana/Marengo", "America/Indiana/Petersburg", "America/Indiana/Tell_City", "America/Indiana/Vevay", "America/Indiana/Vincennes", "America/Indiana/Winamac", "America/Indianapolis", "America/Inuvik", "America/Iqaluit", "America/Jamaica", "America/Jujuy", "America/Juneau", "America/Kentucky/Monticello", "America/Kralendijk", "America/La_Paz", "America/Lima", "America/Los_Angeles", "America/Louisville", "America/Lower_Princes", "America/Maceio", "America/Managua", "America/Manaus", "America/Marigot", "America/Martinique", "America/Matamoros", "America/Mazatlan", "America/Mendoza", "America/Menominee", "America/Merida", "America/Metlakatla", "America/Mexico_City", "America/Miquelon", "America/Moncton", "America/Monterrey", "America/Montevideo", "America/Montserrat", "America/Nassau", "America/New_York", "America/Nome", "America/Noronha", "America/North_Dakota/Beulah", "America/North_Dakota/Center", "America/North_Dakota/New_Salem", "America/Ojinaga", "America/Panama", "America/Paramaribo", "America/Phoenix", "America/Port-au-Prince", "America/Port_of_Spain", "America/Porto_Velho", "America/Puerto_Rico", "America/Punta_Arenas", "America/Rankin_Inlet", "America/Recife", "America/Regina", "America/Resolute", "America/Rio_Branco", "America/Santarem", "America/Santiago", "America/Santo_Domingo", "America/Sao_Paulo", "America/Scoresbysund", "America/Sitka", "America/St_Barthelemy", "America/St_Johns", "America/St_Kitts", "America/St_Lucia", "America/St_Thomas", "America/St_Vincent", "America/Swift_Current", "America/Tegucigalpa", "America/Thule", "America/Tijuana", "America/Toronto", "America/Tortola", "America/Vancouver", "America/Whitehorse", "America/Winnipeg", "America/Yakutat", "Antarctica/Casey", "Antarctica/Davis", "Antarctica/DumontDUrville", "Antarctica/Macquarie", "Antarctica/Mawson", "Antarctica/McMurdo", "Antarctica/Palmer", "Antarctica/Rothera", "Antarctica/Syowa", "Antarctica/Troll", "Antarctica/Vostok", "Arctic/Longyearbyen", "Asia/Aden", "Asia/Almaty", "Asia/Amman", "Asia/Anadyr", "Asia/Aqtau", "Asia/Aqtobe", "Asia/Ashgabat", "Asia/Atyrau", "Asia/Baghdad", "Asia/Bahrain", "Asia/Baku", "Asia/Bangkok", "Asia/Barnaul", "Asia/Beirut", "Asia/Bishkek", "Asia/Brunei", "Asia/Calcutta", "Asia/Chita", "Asia/Colombo", "Asia/Damascus", "Asia/Dhaka", "Asia/Dili", "Asia/Dubai", "Asia/Dushanbe", "Asia/Famagusta", "Asia/Gaza", "Asia/Hebron", "Asia/Hong_Kong", "Asia/Hovd", "Asia/Irkutsk", "Asia/Jakarta", "Asia/Jayapura", "Asia/Jerusalem", "Asia/Kabul", "Asia/Kamchatka", "Asia/Karachi", "Asia/Katmandu", "Asia/Khandyga", "Asia/Krasnoyarsk", "Asia/Kuala_Lumpur", "Asia/Kuching", "Asia/Kuwait", "Asia/Macau", "Asia/Magadan", "Asia/Makassar", "Asia/Manila", "Asia/Muscat", "Asia/Nicosia", "Asia/Novokuznetsk", "Asia/Novosibirsk", "Asia/Omsk", "Asia/Oral", "Asia/Phnom_Penh", "Asia/Pontianak", "Asia/Pyongyang", "Asia/Qatar", "Asia/Qostanay", "Asia/Qyzylorda", "Asia/Rangoon", "Asia/Riyadh", "Asia/Saigon", "Asia/Sakhalin", "Asia/Samarkand", "Asia/Seoul", "Asia/Shanghai", "Asia/Singapore", "Asia/Srednekolymsk", "Asia/Taipei", "Asia/Tashkent", "Asia/Tbilisi", "Asia/Tehran", "Asia/Thimphu", "Asia/Tokyo", "Asia/Tomsk", "Asia/Ulaanbaatar", "Asia/Urumqi", "Asia/Ust-Nera", "Asia/Vientiane", "Asia/Vladivostok", "Asia/Yakutsk", "Asia/Yekaterinburg", "Asia/Yerevan", "Atlantic/Azores", "Atlantic/Bermuda", "Atlantic/Canary", "Atlantic/Cape_Verde", "Atlantic/Faeroe", "Atlantic/Madeira", "Atlantic/Reykjavik", "Atlantic/South_Georgia", "Atlantic/St_Helena", "Atlantic/Stanley", "Australia/Adelaide", "Australia/Brisbane", "Australia/Broken_Hill", "Australia/Darwin", "Australia/Eucla", "Australia/Hobart", "Australia/Lindeman", "Australia/Lord_Howe", "Australia/Melbourne", "Australia/Perth", "Australia/Sydney", "Europe/Amsterdam", "Europe/Andorra", "Europe/Astrakhan", "Europe/Athens", "Europe/Belgrade", "Europe/Berlin", "Europe/Bratislava", "Europe/Brussels", "Europe/Bucharest", "Europe/Budapest", "Europe/Busingen", "Europe/Chisinau", "Europe/Copenhagen", "Europe/Dublin", "Europe/Gibraltar", "Europe/Guernsey", "Europe/Helsinki", "Europe/Isle_of_Man", "Europe/Istanbul", "Europe/Jersey", "Europe/Kaliningrad", "Europe/Kiev", "Europe/Kirov", "Europe/Lisbon", "Europe/Ljubljana", "Europe/London", "Europe/Luxembourg", "Europe/Madrid", "Europe/Malta", "Europe/Mariehamn", "Europe/Minsk", "Europe/Monaco", "Europe/Moscow", "Europe/Oslo", "Europe/Paris", "Europe/Podgorica", "Europe/Prague", "Europe/Riga", "Europe/Rome", "Europe/Samara", "Europe/San_Marino", "Europe/Sarajevo", "Europe/Saratov", "Europe/Simferopol", "Europe/Skopje", "Europe/Sofia", "Europe/Stockholm", "Europe/Tallinn", "Europe/Tirane", "Europe/Ulyanovsk", "Europe/Vaduz", "Europe/Vatican", "Europe/Vienna", "Europe/Vilnius", "Europe/Volgograd", "Europe/Warsaw", "Europe/Zagreb", "Europe/Zurich", "Indian/Antananarivo", "Indian/Chagos", "Indian/Christmas", "Indian/Cocos", "Indian/Comoro", "Indian/Kerguelen", "Indian/Mahe", "Indian/Maldives", "Indian/Mauritius", "Indian/Mayotte", "Indian/Reunion", "Pacific/Apia", "Pacific/Auckland", "Pacific/Bougainville", "Pacific/Chatham", "Pacific/Easter", "Pacific/Efate", "Pacific/Enderbury", "Pacific/Fakaofo", "Pacific/Fiji", "Pacific/Funafuti", "Pacific/Galapagos", "Pacific/Gambier", "Pacific/Guadalcanal", "Pacific/Guam", "Pacific/Honolulu", "Pacific/Kiritimati", "Pacific/Kosrae", "Pacific/Kwajalein", "Pacific/Majuro", "Pacific/Marquesas", "Pacific/Midway", "Pacific/Nauru", "Pacific/Niue", "Pacific/Norfolk", "Pacific/Noumea", "Pacific/Pago_Pago", "Pacific/Palau", "Pacific/Pitcairn", "Pacific/Ponape", "Pacific/Port_Moresby", "Pacific/Rarotonga", "Pacific/Saipan", "Pacific/Tahiti", "Pacific/Tarawa", "Pacific/Tongatapu", "Pacific/Truk", "Pacific/Wake", "Pacific/Wallis", ]
ocre::i18n
ocre::i18n::check(fn): Checks locale files for syntax errors and keys missing from non-default locales.pub fn check(sources: &[(&str, &str)]) -> Vec<Problem>ocre::i18n::layer(fn): Makes the catalog available to theI18nextractor, as an axum layer.pub fn layer(locales: &'static Locales) -> Extension<&'static Catalog>ocre::i18n::Catalog(struct): All locales of an app, parsed: one table of dotted keys per locale code, the first being the default.pub struct Catalogocre::i18n::Catalog::load(fn): Parses(code, file contents)pairs into a catalog; the first pair is the default locale.pub fn load(sources: &[(&'static str, &'static str)]) -> Selfocre::i18n::Catalog::errors(fn): Parse errors fromload, one line each (locales/fr.yml line 3: ...).pub fn errors(&self) -> &[String]ocre::i18n::Catalog::default_locale(fn): Returns the default locale code: the first code given tolocales!.pub fn default_locale(&self) -> &'static strocre::i18n::Catalog::codes(fn): Returns every locale code, default first, e.g. for a language switcher.pub fn codes(&self) -> impl Iterator<Item = &'static str> + '_ocre::i18n::Catalog::locale(fn): Returns translations in localecode, for code outside requests such as mailers and jobs.pub fn locale(&'static self, code: &str) -> I18n- Implements:
Debug
ocre::i18n::HtmlTranslation(struct): ATranslationwritten as HTML, fromTranslation::html: the text as is, every value escaped.pub struct HtmlTranslation<'a>(/* private fields */)- Implements:
Clone,Debug,Display,HtmlSafe
- Implements:
ocre::i18n::I18n(struct): Axum extractor giving translations in the request’s locale, like Rails’I18n.twith a per-request locale.pub struct I18nocre::i18n::I18n::l(fn): Formats a date or time with a format of the locale, like Rails’l(value, format: :short).pub fn l(&self, value: impl fmt::Display, format: &str) -> Stringocre::i18n::I18n::number(fn): Groups thousands and writes the decimal separator of the locale:1 234 567,5in French.pub fn number(&self, value: impl fmt::Display) -> Stringocre::i18n::I18n::number_with_precision(fn): Rounds toprecisiondecimals with the locale’s decimal separator:3,14in French.pub fn number_with_precision(&self, value: impl fmt::Display, precision: usize) -> Stringocre::i18n::I18n::currency(fn): Formats an amount with two decimals andunitplaced as the locale does:1 234,50 €in French.pub fn currency(&self, value: impl fmt::Display, unit: &str) -> Stringocre::i18n::I18n::time_ago_in_words(fn): The time fromvaluetonowin words, in the locale:environ 3 heures.pub fn time_ago_in_words(&self, value: impl fmt::Display) -> Stringocre::i18n::I18n::distance_of_time_in_words(fn): The time between two times in words, in the locale (Rails’distance_of_time_in_words).pub fn distance_of_time_in_words(&self, from: impl fmt::Display, to: impl fmt::Display) -> Stringocre::i18n::I18n::model_name(fn): The name of a model forcountitems, frommodels.<model>(Rails’Post.model_name.human(count:)).pub fn model_name(&self, model: &str, count: impl Count) -> Stringocre::i18n::I18n::attribute(fn): The name of a model’s field, fromattributes.<model>.<field>, thenattributes.<field>(Rails’human_attribute_name).pub fn attribute(&self, model: &str, field: &str) -> Stringocre::i18n::I18n::error_message(fn): The message of a validation error in the locale, without the field name (Rails’errors.messages).pub fn error_message(&self, model: &str, error: &FieldError) -> Stringocre::i18n::I18n::full_message(fn): The translated field name and message of a validation error, aserrors.formatlays them out (Rails’full_message).pub fn full_message(&self, model: &str, error: &FieldError) -> Stringocre::i18n::I18n::locale(fn): Returns the locale code, e.g. for<html lang="{{ i18n.locale() }}">.pub fn locale(&self) -> &'static strocre::i18n::I18n::codes(fn): Returns every locale code of the app, default first, e.g. for a language switcher.pub fn codes(&self) -> impl Iterator<Item = &'static str> + 'staticocre::i18n::I18n::t(fn): Starts the translation of a dotted key, like Rails’t("posts.created").pub fn t<'a>(&self, key: &'a str) -> Translation<'a>ocre::i18n::I18n::scope(fn): Returns the same translations withscopeas the prefix of keys starting with.(Rails’ lazy lookup).pub fn scope(&self, scope: &'static str) -> Selfocre::i18n::I18n::in_locale(fn): Returns the same translations in localecode(Rails’locale:option), keeping the scope.pub fn in_locale(&self, code: &str) -> Selfocre::i18n::I18n::exists(fn): Whetherkeyhas a translation: in the locale, the default locale or the built-in translations.pub fn exists(&self, key: &str) -> boolocre::i18n::I18n::namespace(fn): Returns every translation underprefix, by key relative to it (Rails’ namespace lookup).pub fn namespace(&self, prefix: &str) -> BTreeMap<&'static str, &'static str>ocre::i18n::I18n::path(fn): Prefixespathwith the locale, for routes nested under/{locale}(Rails’default_url_options).pub fn path(&self, path: &str) -> Stringocre::i18n::I18n::alternates(fn): The absolute URL ofpathin every locale, the default first:(code, base_url + "/<code>" + path), for a sitemap’s alternates (Sitemap::add_localized).pub fn alternates(&self, base_url: &str, path: &str) -> Vec<(&'static str, String)>ocre::i18n::I18n::alternate_links(fn): The<link>elements a localized page’s<head>needs:canonical(this locale’s URL), onealternateper locale with itshreflang, andx-default(the default locale’s URL).pub fn alternate_links(&self, base_url: &str, path: &str) -> Stringocre::i18n::I18n::cookie(fn): Returns aSet-Cookievalue remembering this locale for a year.pub fn cookie(&self) -> String- Implements:
Clone,Copy,Debug,FromRequestParts
ocre::i18n::Translation(struct): A translation being built byI18n::t, displayed (looked up and interpolated) when written.pub struct Translation<'a>ocre::i18n::Translation::arg(fn): Sets the value for the%{name}placeholder.pub fn arg(mut self, name: &'a str, value: impl fmt::Display) -> Selfocre::i18n::Translation::count(fn): Sets the plural count: picks the form fornand fills%{count}.pub fn count(mut self, n: impl Count) -> Selfocre::i18n::Translation::or_key(fn): Tries another key when this one has no translation (Rails’default: :"other.key").pub fn or_key(mut self, key: &'a str) -> Selfocre::i18n::Translation::or(fn): Usestextwhen neither the key nor its alternatives have a translation (Rails’default: "text").pub fn or(mut self, text: impl Into<Cow<'a, str>>) -> Selfocre::i18n::Translation::html(fn): Marks the translation as HTML: its text is written as is, the values ofargescaped.pub fn html(self) -> HtmlTranslation<'a>- Implements:
Clone,Debug,Display
ocre::i18n::Problem(enum): A problem in the locale files, found bycheck.pub enum Problemocre::i18n::Problem::Invalid(variant): The file is not valid locale YAML; nothing in it is used.Invalid { locale: String, line: usize, message: String, }ocre::i18n::Problem::Missing(variant): A key of the default locale (or a plural form this language needs) is missing fromlocale.Missing { locale: String, key: String, }- Implements:
Clone,Debug,Display,PartialEq
ocre::i18n::Count(trait): A numberTranslation::countaccepts: every integer type, and references to them.pub trait Countocre::i18n::Count::to_count(fn): Returns the number asi64, ori64::MAXwhen it does not fit.fn to_count(&self) -> i64
ocre::i18n::Locales(type): The app’s translations: aCatalogparsed on first use, declared once as astatic.pub type Locales = LazyLock<Catalog>ocre::i18n::LOCALE_COOKIE(const): Name of the cookie that remembers a visitor’s chosen locale.pub const LOCALE_COOKIE: &str = "locale"ocre::i18n::LOCALE_PARAM(const): Name of the path parameterI18nreads the locale from.pub const LOCALE_PARAM: &str = "locale"
ocre::jobs
ocre::jobs::consume(fn): Runs a batch of queue messages through the app’sperform; the Worker’squeueentry point.pub async fn consume<J, F, Fut>(batch: MessageBatch<String>, env: Env, perform: F) -> worker::Result<()> where J: DeserializeOwned, F: Fn(Ctx, J) -> Fut, Fut: Future<Output = Result<()>>ocre::jobs::cron(fn): Runs the app’s task for the Cron Trigger that fired; the Worker’sscheduledentry point.pub async fn cron<F, Fut>(event: ScheduledEvent, env: Env, run: F) where F: FnOnce(Ctx, String) -> Fut, Fut: Future<Output = Result<()>>ocre::jobs::dev_routes(fn): Development endpoint listing recent jobs, served byocre devonly, for tests (Rails’assert_enqueued_withandassert_performed_jobs).pub fn dev_routes<S: Clone + Send + Sync + 'static>() -> axum::Router<S>ocre::jobs::enqueue(fn): Sendsjobto theJOBSqueue, to run in the background throughconsume.pub fn enqueue<J: Serialize>(ctx: &Ctx, job: &J) -> impl Future<Output = Result<()>> + Send + use<J>ocre::jobs::enqueue_all(fn): Sends every job ofjobsto theJOBSqueue in as few calls as possible, like Rails’perform_all_later.pub fn enqueue_all<J: Serialize>(ctx: &Ctx, jobs: &[J]) -> impl Future<Output = Result<()>> + Send + use<J>ocre::jobs::enqueue_in(fn): Sendsjobto theJOBSqueue likeenqueue, to run afterdelay.pub fn enqueue_in<J: Serialize>(ctx: &Ctx, job: &J, delay: Duration) -> impl Future<Output = Result<()>> + Send + use<J>ocre::jobs::lock(fn): Takes the lockkeyforowneruntilttlseconds from now;falsewhen another owner holds it and it has not expired.pub async fn lock(db: &crate::Db, key: &str, owner: &str, ttl: i64) -> Result<bool>ocre::jobs::queue(fn): A named queue, for jobs that must not wait behind others:ocre::jobs::queue(&ctx, "urgent").enqueue(&job).pub fn queue(ctx: &Ctx, name: &'static str) -> Queueocre::jobs::run_steps(fn): Runsstepfromcursorwhilebudgetcovers itscost(the calls one step makes), for work too large for one invocation: a page of rows per step, the next page’s cursor between them (Active Job’s continuations).pub async fn run_steps<C, F, Fut>(budget: &Budget, cost: u32, mut cursor: C, mut step: F) -> Result<Option<C>> where F: FnMut(C) -> Fut, Fut: Future<Output = Result<Step<C>>>ocre::jobs::unlock(fn): Releases the lockkeyifownerholds it.pub async fn unlock(db: &crate::Db, key: &str, owner: &str) -> Result<()>ocre::jobs::Budget(struct): How many calls an invocation may still make: D1 queries,fetches, KV and R2 operations, as the job counts them.pub struct Budgetocre::jobs::Budget::FREE_D1_QUERIES(const): D1 queries per invocation on the free plan: 50.pub const FREE_D1_QUERIES: u32 = 50ocre::jobs::Budget::FREE_SUBREQUESTS(const): Subrequests (fetch) per invocation on the free plan: 50.pub const FREE_SUBREQUESTS: u32 = 50ocre::jobs::Budget::new(fn): A budget ofcalls.pub fn new(calls: u32) -> Selfocre::jobs::Budget::take(fn): Takescallsfrom the budget when that many are left;false(and nothing taken) otherwise.pub fn take(&self, calls: u32) -> boolocre::jobs::Budget::left(fn): The calls not taken yet.pub fn left(&self) -> u32- Implements:
Debug
ocre::jobs::Queue(struct): A job queue, fromqueue: enqueue on it like on the default queue.pub struct Queueocre::jobs::Queue::enqueue(fn): Sendsjobto this queue, likeenqueuedoes todefault.pub fn enqueue<J: Serialize>(&self, job: &J) -> impl Future<Output = Result<()>> + Send + use<J>ocre::jobs::Queue::enqueue_in(fn): Sendsjobto this queue, to run afterdelay(24 hours at most), likeenqueue_in.pub fn enqueue_in<J: Serialize>(&self, job: &J, delay: Duration) -> impl Future<Output = Result<()>> + Send + use<J>ocre::jobs::Queue::enqueue_all(fn): Sends every job ofjobsto this queue in batches, likeenqueue_all.pub fn enqueue_all<J: Serialize>(&self, jobs: &[J]) -> impl Future<Output = Result<()>> + Send + use<J>- Implements:
Clone,Debug
ocre::jobs::Step(enum): What a step ofrun_stepsdid: more to do from the cursor, or done.pub enum Step<C>ocre::jobs::Step::Next(variant): Continue from this cursor (the next page, the last id handled).Next(C)ocre::jobs::Step::Done(variant): Nothing left.Done- Implements:
Clone,Debug,Eq,PartialEq
ocre::jobs::CRON_LOG_PREFIX(const): Prefix of every line Ocre logs about Cron Triggers, e.g.[ocre cron] 0 3 * * * done.pub const CRON_LOG_PREFIX: &str = "[ocre cron]"ocre::jobs::DEFAULT_QUEUE(const): Name of the queueenqueueandenqueue_inuse:default, bound asQUEUE_BINDING.pub const DEFAULT_QUEUE: &str = "default"ocre::jobs::LOCKS_TABLE_SQL(const): Thejob_lockstable oflockandunlock, created by the migration ofocre g job --lock.pub const LOCKS_TABLE_SQL: &str = "CREATE TABLE job_locks (key TEXT PRIMARY KEY, owner TEXT NOT NULL, expires_at INTEGER NOT NULL)ocre::jobs::LOG_PREFIX(const): Prefix of every line Ocre logs about jobs, e.g.[ocre jobs] send_welcome done.pub const LOG_PREFIX: &str = "[ocre jobs]"ocre::jobs::MAX_DELAY(const): Longest delay Cloudflare Queues accepts: 24 hours, forenqueue_inand retries.pub const MAX_DELAY: Duration = Duration::from_secs(24 * 60 * 60)ocre::jobs::QUEUE_BINDING(const): Name of the queue producer binding every Ocre app sends jobs to.pub const QUEUE_BINDING: &str = "JOBS"
ocre::jwt
ocre::jwt::decode(fn): Verifies a token from a client with the key derived fromSECRET_KEY_BASEand returns its claims.pub fn decode(ctx: &Ctx, token: &str) -> Result<Claims>ocre::jwt::decode_with(fn): Verifiestokenwithkeyat Unix timenow(seconds) and returns its claims.pub fn decode_with(key: &Key, token: &str, now: i64) -> Result<Claims>ocre::jwt::encode(fn): Signsclaimswith the HS256 key derived from theSECRET_KEY_BASEWorker secret.pub fn encode(ctx: &Ctx, claims: &Claims) -> Result<String>ocre::jwt::encode_with(fn): Signsclaimswithkeyand returns the compact tokenheader.payload.signature.pub fn encode_with(key: &Key, claims: &Claims) -> Stringocre::jwt::token_from(fn): The token of the firstlocationsentry that has a non-empty one.pub fn token_from(headers: &HeaderMap, uri: &Uri, locations: &[Location]) -> Option<String>ocre::jwt::Claims(struct): The payload of a token: who it is for and when it expires.pub struct Claimsocre::jwt::Claims::sub(field): Subject: the user id, as a string (the JWT standard’s type).pub sub: Stringocre::jwt::Claims::iat(field): Issued at, in Unix seconds.pub iat: i64ocre::jwt::Claims::exp(field): Expires at, in Unix seconds; the token is rejected from this second on.pub exp: i64ocre::jwt::Claims::new(fn): Claims forsub, issued now (crate::now) and valid forttl_seconds.pub fn new(sub: impl Into<String>, ttl_seconds: i64) -> Self- Implements:
Clone,Debug,Deserialize,Eq,PartialEq,Serialize
ocre::jwt::Key(struct): An HS256 signing key, derived fromSECRET_KEY_BASE.pub struct Key(/* private fields */)ocre::jwt::Key::from_secret_key_base(fn): Derives the key from aSECRET_KEY_BASEvalue: HMAC-SHA256 of a fixed label.pub fn from_secret_key_base(secret: &str) -> Self
ocre::jwt::Location(enum): Wheretoken_fromlooks for a token (Loco’sauth.jwt.location).pub enum Locationocre::jwt::Location::Bearer(variant):Authorization: Bearer <token>, the default for API clients.Bearerocre::jwt::Location::Query(variant): A query parameter, e.g.Query("token")for?token=....Query(&'static str)ocre::jwt::Location::Cookie(variant): A cookie, e.g.Cookie("token").Cookie(&'static str)- Implements:
Clone,Copy,Debug,Eq,PartialEq
ocre::jwt::ALGORITHM(const): The only JWT algorithm Ocre signs with and accepts:HS256(HMAC-SHA256).pub const ALGORITHM: &str = "HS256"
ocre::log
ocre::log::Logger(struct): Writes log lines with a set of fields; cheap to clone (see the module documentation).pub struct Loggerocre::log::Logger::new(fn): A logger without fields.pub fn new() -> Selfocre::log::Logger::with(fn): A copy of this logger with one more field on every line (Rails’logger.tagged).pub fn with(&self, key: &str, value: impl Serialize) -> Selfocre::log::Logger::field(fn): The value of a field, e.g.request_id.pub fn field(&self, key: &str) -> Option<&Value>ocre::log::Logger::enabled(fn): Whether lines oflevelare written, under the currentLOG_LEVEL.pub fn enabled(&self, level: Level) -> boolocre::log::Logger::debug(fn): Writes adebugline.pub fn debug(&self, message: impl Display)ocre::log::Logger::info(fn): Writes aninfoline.pub fn info(&self, message: impl Display)ocre::log::Logger::warn(fn): Writes awarnline.pub fn warn(&self, message: impl Display)ocre::log::Logger::error(fn): Writes anerrorline.pub fn error(&self, message: impl Display)ocre::log::Logger::log(fn): Writes a line oflevelwhen it is enabled; the message is formatted only then.pub fn log(&self, level: Level, message: &dyn Display)ocre::log::Logger::line(fn): The linelogwrites, whatever the current level: JSON or text.pub fn line(&self, level: Level, message: &str, format: Format) -> String- Implements:
Clone,Debug,Default
ocre::log::Format(enum): How log lines are written: see the module documentation.pub enum Formatocre::log::Format::Json(variant): One JavaScript object per line, indexed by Workers Logs.Jsonocre::log::Format::Text(variant):LEVEL message key=value ..., for the terminal.Textocre::log::Format::parse(fn): Reads a format name:json, ortext(prettyandcompactaccepted, like Loco).pub fn parse(name: &str) -> Option<Self>- Implements:
Clone,Copy,Debug,Eq,PartialEq
ocre::log::Level(enum): Severity of a log line (Rails’:debug,:info,:warn,:error).pub enum Levelocre::log::Level::Debug(variant): Details for development: SQL statements, request summaries.Debugocre::log::Level::Info(variant): Normal events worth keeping in production.Infoocre::log::Level::Warn(variant): Something unexpected that the app handled.Warnocre::log::Level::Error(variant): A failure: internal errors, failed jobs.Errorocre::log::Level::parse(fn): Reads a level name, case-insensitively:debug,info,warn(warning),error(fatal,unknown).pub fn parse(name: &str) -> Option<Self>ocre::log::Level::as_str(fn): The lowercase name written in log lines:debug,info,warn,error.pub fn as_str(self) -> &'static str- Implements:
Clone,Copy,Debug,Eq,Hash,Ord,PartialEq,PartialOrd
ocre::log::LOG_FORMAT(const): Worker variable choosing the line format:jsonortext.pub const LOG_FORMAT: &str = "LOG_FORMAT"ocre::log::LOG_LEVEL(const): Worker variable setting the lowest level logged:debug,info,warn,errororoff.pub const LOG_LEVEL: &str = "LOG_LEVEL"
ocre::mail
ocre::mail::address_with_name(fn): FormatsName <address>, quoting the name when needed, like Rails’email_address_with_name.pub fn address_with_name(name: &str, address: &str) -> Stringocre::mail::deliver_in(fn): Checksemailnow and sends it from the jobs queue afterdelay, like Rails’deliver_later(wait:).pub fn deliver_in(ctx: &Ctx, email: Email, delay: Duration) -> impl Future<Output = Result<()>> + Send + use<>ocre::mail::deliver_later(fn): Checksemailnow and sends it later from the background jobs queue, like Rails’deliver_later.pub fn deliver_later(ctx: &Ctx, email: Email) -> impl Future<Output = Result<()>> + Send + use<>ocre::mail::dev_routes(fn): Development pages for email, served byocre devonly, like Rails’/rails/mailersand Action Mailbox’s conductor.pub fn dev_routes<S: Clone + Send + Sync + 'static>(previews: &'static [Preview]) -> Router<S>ocre::mail::receive(fn): Runs the app’s mailboxhandlerfor an email from Cloudflare Email Routing; the Worker’semailentry point.pub async fn receive<F, Fut>(message: ForwardableEmailMessage, env: Env, handler: F) -> worker::Result<()> where F: FnOnce(Ctx, InboundEmail) -> Fut, Fut: Future<Output = Result<()>>ocre::mail::send(fn): Sendsemailnow, fromMAIL_FROM, with the adapter named byMAIL_ADAPTER.pub fn send(ctx: &Ctx, email: Email) -> impl Future<Output = Result<()>> + Send + use<>ocre::mail::url(fn): An absolute URL forpathon the app’s public address, theAPP_URLvariable (Rails’_urlhelpers in mailers).pub fn url(ctx: &Ctx, path: &str) -> Result<String>ocre::mail::Attachment(struct): A file attached to anEmail, or an inline image shown by its HTML.pub struct Attachmentocre::mail::Attachment::filename(field): File name shown by mail clients,invoice.pdf.pub filename: Stringocre::mail::Attachment::content_type(field): MIME type,application/pdforimage/png.pub content_type: Stringocre::mail::Attachment::content(field): The file’s bytes.pub content: Vec<u8>ocre::mail::Attachment::content_id(field): For inline images: the id the HTML refers to ascid:<id>.pub content_id: Option<String>- Implements:
Clone,Debug,Deserialize,PartialEq,Serialize
ocre::mail::Email(struct): An outgoing email: recipients, a subject, a plain-text body, and optionally HTML, headers and attachments.pub struct Emailocre::mail::Email::from(field): Sender, when notMAIL_FROM:billing@example.comorBilling <billing@example.com>, on a domain verified with the provider.pub from: Option<String>ocre::mail::Email::to(field):Torecipients,ada@example.comorAda <ada@example.com>; an invalid one makes sending a 400.pub to: Vec<String>ocre::mail::Email::cc(field):Ccrecipients, checked liketo.pub cc: Vec<String>ocre::mail::Email::bcc(field):Bccrecipients, checked liketo; the other recipients do not see them.pub bcc: Vec<String>ocre::mail::Email::subject(field): Subject line: one non-empty line of text.pub subject: Stringocre::mail::Email::text(field): Plain-text body; always sent, so every mail client can read it.pub text: Stringocre::mail::Email::html(field): Optional HTML body, shown instead oftextby clients that render HTML.pub html: Option<String>ocre::mail::Email::reply_to(field): Where replies go, when not to the sender; checked liketo.pub reply_to: Option<String>ocre::mail::Email::headers(field): Extra headers,(name, value): threading (In-Reply-To,References),List-Unsubscribe,X-....pub headers: Vec<(String, String)>ocre::mail::Email::attachments(field): Files attached to the email, and inline images the HTML shows withcid:.pub attachments: Vec<Attachment>ocre::mail::Email::delivery_method(field): Adapter for this email instead ofMAIL_ADAPTER(resendorcloudflare), set bydelivery_method; ignored whileMAIL_ADAPTERislog.pub delivery_method: Option<String>ocre::mail::Email::new(fn): Creates a text-only email to one recipient.pub fn new(to: impl Into<String>, subject: impl Into<String>, text: impl Into<String>) -> Selfocre::mail::Email::also_to(fn): Adds anotherTorecipient.pub fn also_to(mut self, address: impl Into<String>) -> Selfocre::mail::Email::cc(fn): Adds aCcrecipient.pub fn cc(mut self, address: impl Into<String>) -> Selfocre::mail::Email::bcc(fn): Adds aBccrecipient: it gets the email, the other recipients do not see it.pub fn bcc(mut self, address: impl Into<String>) -> Selfocre::mail::Email::from(fn): Sends fromaddressinstead of theMAIL_FROMvariable.pub fn from(mut self, address: impl Into<String>) -> Selfocre::mail::Email::delivery_method(fn): Sends this email with another adapter thanMAIL_ADAPTER:"resend"or"cloudflare"(Rails’delivery_method).pub fn delivery_method(mut self, adapter: impl Into<String>) -> Selfocre::mail::Email::html(fn): Adds the HTML version of the body, replacing any previous one.pub fn html(mut self, html: impl Into<String>) -> Selfocre::mail::Email::reply_to(fn): Sets theReply-Toaddress, so replies go there instead of to the sender.pub fn reply_to(mut self, address: impl Into<String>) -> Selfocre::mail::Email::header(fn): Adds a header, e.g.In-Reply-ToandReferencesto thread a reply, orList-Unsubscribe.pub fn header(mut self, name: impl Into<String>, value: impl Into<String>) -> Selfocre::mail::Email::attach(fn): Attaches a file, like Rails’attachments["invoice.pdf"] = bytes.pub fn attach(mut self, filename: impl Into<String>, content_type: impl Into<String>, content: Vec<u8>) -> Selfocre::mail::Email::inline(fn): Embeds an image that the HTML shows with<img src="cid:<content_id>">, like Rails’attachments.inline.pub fn inline(mut self, content_id: impl Into<String>, filename: impl Into<String>, content_type: impl Into<String>, content: Vec<u8>) -> Self- Implements:
Clone,Debug,Deserialize,PartialEq,Serialize
ocre::mail::InboundEmail(struct): An email that Cloudflare Email Routing delivered to the Worker, handed to the app’s mailbox.pub struct InboundEmailocre::mail::InboundEmail::from(fn): Returns the envelope sender (SMTPMAIL FROM), checked by Cloudflare.pub fn from(&self) -> &strocre::mail::InboundEmail::to(fn): Returns the envelope recipient: the address of this app that received the email.pub fn to(&self) -> &strocre::mail::InboundEmail::subject(fn): Returns the decodedSubjectheader, or""when it is missing.pub fn subject(&self) -> &strocre::mail::InboundEmail::header(fn): Returns the first header with this name (case-insensitive), decoded.pub fn header(&self, name: &str) -> Option<&str>ocre::mail::InboundEmail::headers(fn): Returns every header, in message order, as decoded(name, value)pairs.pub fn headers(&self) -> &[(String, String)]ocre::mail::InboundEmail::text(fn): Returns the firsttext/plainpart, decoded to UTF-8, orNonewhen there is none.pub fn text(&self) -> Option<&str>ocre::mail::InboundEmail::attachments(fn): Returns the files of the email, decoded: every part that is not the first text or HTML body.pub fn attachments(&self) -> &[Attachment]ocre::mail::InboundEmail::html(fn): Returns the firsttext/htmlpart, decoded to UTF-8, orNonewhen there is none.pub fn html(&self) -> Option<&str>ocre::mail::InboundEmail::raw(fn): Returns the whole message as received (RFC 5322 bytes), e.g. to store it in R2 or read attachments.pub fn raw(&self) -> &[u8]ocre::mail::InboundEmail::reject(fn): Bounces the email: the sending server gets a permanent SMTP error withreason.pub fn reject(&self, reason: &str)ocre::mail::InboundEmail::forward(fn): Forwards the email unchanged toto, which must be a verified destination address of the Cloudflare account.pub async fn forward(&self, to: &str) -> Result<()>
ocre::mail::Preview(struct): A mailer action shown at/ocre/dev/mailersinocre dev, rendered with sample data, like Rails’ mailer previews.pub struct Previewocre::mail::Preview::name(field):mailer/action, e.g.user/welcome; the page’s URL is/ocre/dev/mailers/preview/<name>.pub name: &'static strocre::mail::Preview::build(field): Builds the email with sample data.pub build: fn() -> Result<Email>ocre::mail::Preview::new(fn): A preview namedmailer/action, built bybuild.pub const fn new(name: &'static str, build: fn() -> Result<Email>) -> Self- Implements:
Clone,Copy,Debug
ocre::mail::APP_URL(const): Name of the Worker variable holding the app’s public address,https://shop.example.com, for links in emails.pub const APP_URL: &str = "APP_URL"ocre::mail::EMAIL_BINDING(const): Name of thebindings.sendEmail()binding used whenMAIL_ADAPTER = "cloudflare".pub const EMAIL_BINDING: &str = "EMAIL"ocre::mail::LOG_PREFIX(const): Prefix of every line Ocre logs about mail, e.g. inocre devoutput.pub const LOG_PREFIX: &str = "[ocre mail]"ocre::mail::MAIL_ADAPTER(const): Name of the Worker variable that chooses the adapter:log,resendorcloudflare.pub const MAIL_ADAPTER: &str = "MAIL_ADAPTER"ocre::mail::MAIL_FROM(const): Name of the Worker variable holding the sender address.pub const MAIL_FROM: &str = "MAIL_FROM"ocre::mail::RESEND_API_KEY(const): Name of the Worker secret holding the Resend API key, used whenMAIL_ADAPTER = "resend".pub const RESEND_API_KEY: &str = "RESEND_API_KEY"
ocre::oauth
ocre::oauth::authorize_url(fn): The URL to send the browser to: the provider’s sign-in page for this app.pub fn authorize_url(provider: &Provider, client_id: &str, redirect_uri: &str, state: &str, code_challenge: &str) -> Stringocre::oauth::exchange_code(fn): Trades the authorizationcodefrom the callback for an access token (one subrequest).pub fn exchange_code(ctx: &Ctx, provider: &'static Provider, redirect_uri: &str, code: &str, verifier: &str) -> impl Future<Output = Result<String>> + Send + use<>ocre::oauth::profile(fn): Reads the signed-in user’sProfilewith an access token (one subrequest; two for GitHub).pub fn profile(provider: &'static Provider, access_token: &str) -> impl Future<Output = Result<Profile>> + Send + use<>ocre::oauth::provider(fn): The provider calledname("github","google"), if Ocre knows it.pub fn provider(name: &str) -> Option<&'static Provider>ocre::oauth::Pkce(struct): A PKCE pair (RFC 7636,S256): keep the verifier in the session, send the challenge.pub struct Pkceocre::oauth::Pkce::verifier(field): The secret, sent with the token request (exchange_code).pub verifier: Stringocre::oauth::Pkce::challenge(field):BASE64URL(SHA-256(verifier)), sent in the authorization URL.pub challenge: Stringocre::oauth::Pkce::new(fn): A new random verifier (32 bytes) and its challenge.pub fn new() -> Selfocre::oauth::Pkce::challenge_for(fn): TheS256challenge ofverifier.pub fn challenge_for(verifier: &str) -> String- Implements:
Clone,Debug,Eq,PartialEq
ocre::oauth::Profile(struct): The user a provider signed in: its id there, and its email when verified.pub struct Profileocre::oauth::Profile::provider(field): The provider’sProvider::name.pub provider: &'static strocre::oauth::Profile::uid(field): The user’s stable id at the provider (GitHub’s numeric id, Google’ssub).pub uid: Stringocre::oauth::Profile::email(field): The user’s email, only when the provider says it is verified; lowercased.pub email: Option<String>ocre::oauth::Profile::name(field): The display name, when the user has one.pub name: Option<String>- Implements:
Clone,Debug,Eq,PartialEq
ocre::oauth::Provider(struct): An OAuth 2.0 provider: its endpoints and the scopes Ocre asks for.pub struct Providerocre::oauth::Provider::name(field): Lowercase name, used in routes (/auth/github) and stored with identities.pub name: &'static strocre::oauth::Provider::authorize_url(field): Where the browser is sent to sign in and approve the app.pub authorize_url: &'static strocre::oauth::Provider::token_url(field): Where the Worker trades the code for an access token.pub token_url: &'static strocre::oauth::Provider::userinfo_url(field): Where the Worker reads the signed-in user.pub userinfo_url: &'static strocre::oauth::Provider::scopes(field): Space-separated scopes: the user’s identity and email address only.pub scopes: &'static strocre::oauth::Provider::client_id_secret(field): Name of the Worker secret holding the OAuth app’s client id.pub client_id_secret: &'static strocre::oauth::Provider::client_secret_secret(field): Name of the Worker secret holding the OAuth app’s client secret.pub client_secret_secret: &'static str- Implements:
Debug,Eq,PartialEq
ocre::oauth::GITHUB(const): GitHub (OAuth app or GitHub App): scopesread:user user:email.pub const GITHUB: Provider = Providerocre::oauth::GOOGLE(const): Google (OpenID Connect): scopesopenid email profile.pub const GOOGLE: Provider = Providerocre::oauth::PROVIDERS(const): Every provider Ocre knows:ocre g auth --oauthaccepts these names.pub const PROVIDERS: [&Provider; 2] = [&GITHUB, &GOOGLE]
ocre::password
ocre::password::hash(fn): Hashespasswordwith a new random 16-byte salt into a self-describing digest.pub async fn hash(password: &str) -> Result<String>ocre::password::iterations(fn): The iteration count stored indigest, orNonewhen it is not in Ocre’s format.pub fn iterations(digest: &str) -> Option<u32>ocre::password::verify(fn): Whetherpasswordmatchesdigest(made byhash), compared in constant time.pub async fn verify(password: &str, digest: &str) -> Result<bool>ocre::password::ITERATIONS(const): Iterations for new digests: 100,000, the most Workers’ WebCrypto accepts.pub const ITERATIONS: u32 = 100_000
ocre::push (feature push)
ocre::push::encrypt(fn): Encryptspayloadfor a subscription (aes128gcmcontent coding, RFC 8291), with a new key and salt.pub fn encrypt(keys: &SubscriptionKeys, payload: &[u8]) -> Result<Vec<u8>>ocre::push::message(fn): The message the service worker ofocre g pwashows:{"title", "options": {"body", "data": {"path"}}}; clicking the notification openspath.pub fn message(title: &str, body: &str, path: &str) -> serde_json::Valueocre::push::send(fn): Encryptsmessage(JSON, e.g.message) forsubscriptionand posts it to its push service, signed with the app’s VAPID keys.pub fn send(ctx: &Ctx, subscription: &Subscription, message: &serde_json::Value, ttl: u32) -> impl Future<Output = Result<Sent>> + Send + use<>ocre::push::vapid_authorization(fn): TheAuthorizationheader of a push toendpoint(VAPID, RFC 8292):vapid t=<JWT signed with ES256>, k=<public key>, valid 12 hours.pub fn vapid_authorization(endpoint: &str, subject: &str, keys: &VapidKeys, now: i64) -> Result<String>ocre::push::Subscription(struct): What a browser’sPushSubscription.toJSON()gives: where and how to push to it.pub struct Subscriptionocre::push::Subscription::endpoint(field): The push service URL for this browser.pub endpoint: Stringocre::push::Subscription::keys(field): The browser’s keys.pub keys: SubscriptionKeys- Implements:
Clone,Debug,Deserialize,Eq,PartialEq,Serialize
ocre::push::SubscriptionKeys(struct): The browser’s public key and authentication secret, URL-safe base64.pub struct SubscriptionKeysocre::push::SubscriptionKeys::p256dh(field): P-256 public key (65 bytes, uncompressed).pub p256dh: Stringocre::push::SubscriptionKeys::auth(field): Authentication secret (16 bytes).pub auth: String- Implements:
Clone,Debug,Deserialize,Eq,PartialEq,Serialize
ocre::push::VapidKeys(struct): A VAPID key pair, URL-safe base64 without padding.pub struct VapidKeysocre::push::VapidKeys::public_key(field): The public key (65 bytes, uncompressed point):VAPID_PUBLIC_KEY, given to browsers.pub public_key: Stringocre::push::VapidKeys::private_key(field): The private key (32 bytes):VAPID_PRIVATE_KEY, a secret.pub private_key: Stringocre::push::VapidKeys::generate(fn): A new random key pair.pub fn generate() -> Self- Implements:
Clone,Debug,Eq,PartialEq
ocre::push::Sent(enum): What the push service did with a message.pub enum Sentocre::push::Sent::Delivered(variant): Accepted (201): the browser gets it when it is online, within the TTL.Deliveredocre::push::Sent::Gone(variant): The subscription no longer exists (404 or 410: the user unsubscribed or the browser dropped it): delete it.Gone- Implements:
Clone,Copy,Debug,Eq,PartialEq
ocre::push::MAX_PAYLOAD(const): Largest message, in bytes: one 4,096-byte record less the encryption’s overhead.pub const MAX_PAYLOAD: usize = 4096 - 16 - 1ocre::push::VAPID_PRIVATE_KEY(const): Worker secret holding the private VAPID key (URL-safe base64, 32 bytes).pub const VAPID_PRIVATE_KEY: &str = "VAPID_PRIVATE_KEY"ocre::push::VAPID_PUBLIC_KEY(const): Worker variable holding the public VAPID key (URL-safe base64), which browsers subscribe with.pub const VAPID_PUBLIC_KEY: &str = "VAPID_PUBLIC_KEY"ocre::push::VAPID_SUBJECT(const): Worker variable holding the contact push services may write to:mailto:you@example.comor anhttps:URL.pub const VAPID_SUBJECT: &str = "VAPID_SUBJECT"
ocre::realtime (feature realtime)
ocre::realtime::append(fn): Builds a message that insertshtmlat the end of the element with idtarget(htmxbeforeend).pub fn append(target: &str, html: &str) -> Stringocre::realtime::broadcast(fn): Sendsmessage(an HTML fragment or JSON text) to every browser connected tochannel.pub fn broadcast(ctx: &Ctx, channel: &str, message: &str) -> impl Future<Output = Result<()>> + Send + use<>ocre::realtime::dev_routes(fn): Development endpoint listing recent broadcasts, served byocre devonly, for tests (Rails’assert_broadcasts).pub fn dev_routes<S: Clone + Send + Sync + 'static>() -> Router<S>ocre::realtime::prepend(fn): Builds a message that insertshtmlat the start of the element with idtarget(htmxafterbegin).pub fn prepend(target: &str, html: &str) -> Stringocre::realtime::remove(fn): Builds a message that removes the element with ididfrom the page (htmxdelete).pub fn remove(id: &str) -> Stringocre::realtime::update(fn): Builds a message that replaces the contents of the element with idtarget(htmxinnerHTML).pub fn update(target: &str, html: &str) -> Stringocre::realtime::OcreChannel(struct): The Durable Object class behind each realtime channel, exported by Ocre under the nameOcreChannel.pub struct OcreChannel- Implements:
DurableObject,From
- Implements:
ocre::realtime::WebSocketUpgrade(struct): Axum extractor for a WebSocket handshake (Upgrade: websocket), finished withconnect.pub struct WebSocketUpgradeocre::realtime::WebSocketUpgrade::identified_by(fn): Names who is connecting, like Action Cable’sidentified_by :current_user.pub fn identified_by(mut self, identity: impl Into<String>) -> Selfocre::realtime::WebSocketUpgrade::rebroadcast(fn): Relays what this client sends to the channel’s other subscribers, like a channel that rebroadcasts client data.pub fn rebroadcast(mut self) -> Selfocre::realtime::WebSocketUpgrade::connect(fn): Connects the browser tochannel, returning the101 Switching Protocolsresponse to send back.pub fn connect(self, ctx: &Ctx, channel: &str) -> impl Future<Output = Result<Response>> + Send + use<>- Implements:
Debug,FromRequestParts
ocre::realtime::CHANNELS_BINDING(const): Name of the Durable Object binding holding the channels, declared in cloudflare.config.ts.pub const CHANNELS_BINDING: &str = "CHANNELS"ocre::realtime::CHANNEL_CLASS(const): Name of the Durable Object class Ocre exports for channels (OcreChannel).pub const CHANNEL_CLASS: &str = "OcreChannel"ocre::realtime::LOG_PREFIX(const): Prefix of every line Ocre logs about realtime, e.g. inocre devoutput.pub const LOG_PREFIX: &str = "[ocre realtime]"ocre::realtime::MAX_CHANNEL_LEN(const): Longest channel name, in bytes.pub const MAX_CHANNEL_LEN: usize = 128ocre::realtime::MAX_IDENTITY_LEN(const): Longest identity given toWebSocketUpgrade::identified_by, in bytes.pub const MAX_IDENTITY_LEN: usize = 256ocre::realtime::MAX_REBROADCAST_BYTES(const): Longest client messageWebSocketUpgrade::rebroadcastrelays, in bytes; longer ones are dropped.pub const MAX_REBROADCAST_BYTES: usize = 16 * 1024
ocre::replicas
ocre::replicas::REPLICAS_VAR(const): Worker variable turning replicas on when set toon:D1_REPLICAS.pub const REPLICAS_VAR: &str = "D1_REPLICAS"
ocre::security
ocre::security::escape_javascript(fn): Escapes text for a JavaScript string literal in single, double or back quotes (Rails’escape_javascript).pub fn escape_javascript(text: &str) -> Stringocre::security::filter_json(fn): A JSON value with sensitive values replaced by"[FILTERED]", at any depth.pub fn filter_json(value: &Value) -> Valueocre::security::filter_parameters(fn): A query string or form body with sensitive values replaced by[FILTERED](Rails’filter_parameters).pub fn filter_parameters(query: &str) -> Stringocre::security::json_escape(fn): Escapes a JSON string for a<script>element (Rails’json_escape).pub fn json_escape(json: &str) -> Stringocre::security::rate_limit(fn): Counts one request forkeyagainst the Workers Rate Limiting bindingbinding; 429 when over the limit.pub async fn rate_limit(ctx: &Ctx, binding: &str, key: &str) -> Result<()>ocre::security::sanitize(fn): Cleans user-supplied HTML down toSANITIZE_TAGSandSANITIZE_ATTRIBUTES(Rails’sanitize).pub fn sanitize(html: &str) -> Stringocre::security::sanitize_with(fn): Likesanitize, with your own allowed tags and attributes (Rails’sanitize(html, tags:, attributes:)).pub fn sanitize_with(html: &str, tags: &[&str], attributes: &[&str]) -> Stringocre::security::strip_tags(fn): Removes every tag and comment and keeps the text, escaped (Rails’strip_tags).pub fn strip_tags(html: &str) -> Stringocre::security::url_from(fn): The URL to redirect to whencandidatepoints inside this app, elseNone(Rails’url_from).pub fn url_from(uri: &Uri, candidate: &str) -> Option<String>ocre::security::AllowBrowser(struct): Tower layer that answers406 Not Acceptableto browsers older than the versions it allows (Rails’allow_browser).pub struct AllowBrowserocre::security::AllowBrowser::new(fn): A policy that allows every browser; add limits withminimumanddeny.pub fn new() -> Selfocre::security::AllowBrowser::modern(fn): Rails’allow_browser versions: :modern: Safari 17.2, Chrome and Edge 120, Firefox 121, Opera 106, no Internet Explorer.pub fn modern() -> Selfocre::security::AllowBrowser::minimum(fn): Allowsbrowserfrom versionmajor.minoron; replaces an earlier rule for the same browser.pub fn minimum(self, browser: Browser, major: u32, minor: u32) -> Selfocre::security::AllowBrowser::deny(fn): Refuses every version ofbrowser(Rails’ie: false).pub fn deny(self, browser: Browser) -> Selfocre::security::AllowBrowser::page(fn): Replaces the HTML page sent with the 406 (by default a short “please upgrade your browser” page).pub fn page(mut self, html: impl Into<String>) -> Selfocre::security::AllowBrowser::allows(fn): Whether a request with thisUser-Agentpasses: a missing header or an unknown client always does.pub fn allows(&self, user_agent: Option<&str>) -> bool- Implements:
Clone,Debug,Default,Layer
ocre::security::AllowBrowserService(struct): The service built by theAllowBrowserlayer.pub struct AllowBrowserService<S>- Implements:
Clone,Debug,Service
- Implements:
ocre::security::BasicAuth(struct): HTTP Basic credentials fromAuthorization: Basic ..., as an extractor (Rails’http_basic_authenticate_with).pub struct BasicAuthocre::security::BasicAuth::username(field): The user name the client sent.pub username: Stringocre::security::BasicAuth::password(field): The password the client sent.pub password: Stringocre::security::BasicAuth::matches(fn): Whether the credentials areusernameandpassword, compared in constant time.pub fn matches(&self, username: &str, password: &str) -> boolocre::security::BasicAuth::challenge(fn):401 UnauthorizedwithWWW-Authenticate: Basic realm="Application": the browser asks again.pub fn challenge() -> Response- Implements:
Clone,Debug,Eq,FromRequestParts,PartialEq
ocre::security::ContentSecurityPolicy(struct): AContent-Security-Policyheader, built directive by directive, and the layer that sends it.pub struct ContentSecurityPolicyocre::security::ContentSecurityPolicy::new(fn): An empty policy: add directives with the builder methods.pub fn new() -> Selfocre::security::ContentSecurityPolicy::directive(fn): Sets any directive, e.g.directive("sandbox", &["allow-forms"]); replaces a previous value.pub fn directive(mut self, name: &str, sources: &[&str]) -> Selfocre::security::ContentSecurityPolicy::default_src(fn):default-src: the fallback for every fetch directive not set.pub fn default_src(self, sources: &[&str]) -> Selfocre::security::ContentSecurityPolicy::script_src(fn):script-src: where scripts may come from.pub fn script_src(self, sources: &[&str]) -> Selfocre::security::ContentSecurityPolicy::style_src(fn):style-src: where stylesheets and inline styles may come from.pub fn style_src(self, sources: &[&str]) -> Selfocre::security::ContentSecurityPolicy::img_src(fn):img-src: images and favicons.pub fn img_src(self, sources: &[&str]) -> Selfocre::security::ContentSecurityPolicy::font_src(fn):font-src: web fonts.pub fn font_src(self, sources: &[&str]) -> Selfocre::security::ContentSecurityPolicy::connect_src(fn):connect-src:fetch, XHR (htmx requests), WebSockets andEventSource.pub fn connect_src(self, sources: &[&str]) -> Selfocre::security::ContentSecurityPolicy::media_src(fn):media-src:<audio>and<video>.pub fn media_src(self, sources: &[&str]) -> Selfocre::security::ContentSecurityPolicy::object_src(fn):object-src:<object>and<embed>; set it toNONE.pub fn object_src(self, sources: &[&str]) -> Selfocre::security::ContentSecurityPolicy::frame_src(fn):frame-src: pages this app may put in an<iframe>.pub fn frame_src(self, sources: &[&str]) -> Selfocre::security::ContentSecurityPolicy::frame_ancestors(fn):frame-ancestors: sites that may put this app in a frame (the modernX-Frame-Options).pub fn frame_ancestors(self, sources: &[&str]) -> Selfocre::security::ContentSecurityPolicy::form_action(fn):form-action: where forms may be submitted.pub fn form_action(self, sources: &[&str]) -> Selfocre::security::ContentSecurityPolicy::base_uri(fn):base-uri: allowed<base href>values.pub fn base_uri(self, sources: &[&str]) -> Selfocre::security::ContentSecurityPolicy::upgrade_insecure_requests(fn):upgrade-insecure-requests: browsers loadhttp:resources over HTTPS.pub fn upgrade_insecure_requests(self) -> Selfocre::security::ContentSecurityPolicy::report_uri(fn):report-uri: where browsers POST violation reports (JSON), e.g. a route of the app.pub fn report_uri(self, uri: &str) -> Selfocre::security::ContentSecurityPolicy::report_to(fn):report-to: theReporting-Endpointsgroup violation reports go to.pub fn report_to(self, group: &str) -> Selfocre::security::ContentSecurityPolicy::report_only(fn): SendsContent-Security-Policy-Report-Only: browsers report violations but block nothing.pub fn report_only(mut self) -> Selfocre::security::ContentSecurityPolicy::header_name(fn):content-security-policy, orcontent-security-policy-report-onlyafterreport_only.pub fn header_name(&self) -> HeaderNameocre::security::ContentSecurityPolicy::header_value(fn): The header value, withNONCEreplaced by'nonce-<nonce>'(and dropped whennonceisNone).pub fn header_value(&self, nonce: Option<&str>) -> String- Implements:
Clone,Debug,Default,Eq,Layer,PartialEq
ocre::security::CspNonce(struct): The request’s Content-Security-Policy nonce, as an extractor (Rails’content_security_policy_nonce).pub struct CspNonce(/* private fields */)ocre::security::CspNonce::as_str(fn): The nonce value, without the'nonce-...'wrapper.pub fn as_str(&self) -> &str- Implements:
Clone,Debug,Display,Eq,FromRequestParts,PartialEq
ocre::security::PermissionsPolicy(struct): APermissions-Policyheader, built feature by feature, and the layer that sends it.pub struct PermissionsPolicyocre::security::PermissionsPolicy::new(fn): An empty policy: add features withallowanddeny.pub fn new() -> Selfocre::security::PermissionsPolicy::allow(fn): Allowsfeaturefor the listed origins only; replaces a previous rule for it.pub fn allow(mut self, feature: &str, allowlist: &[&str]) -> Selfocre::security::PermissionsPolicy::deny(fn): Turnsfeaturesoff everywhere:camera=().pub fn deny(self, features: &[&str]) -> Selfocre::security::PermissionsPolicy::header_value(fn): The header value.pub fn header_value(&self) -> String- Implements:
Clone,Debug,Default,Eq,Layer,PartialEq
ocre::security::PolicyService(struct): The service aContentSecurityPolicyorPermissionsPolicylayer wraps routes in.pub struct PolicyService<S, P>- Implements:
Clone,Service
- Implements:
ocre::security::Browser(enum): A browser family thatAllowBrowserrecognizes in theUser-Agentheader.pub enum Browserocre::security::Browser::Chrome(variant): Google Chrome and Chromium (Chrome/,CriOS/on iOS).Chromeocre::security::Browser::Edge(variant): Microsoft Edge (Edg/,EdgA/,EdgiOS/).Edgeocre::security::Browser::Firefox(variant): Mozilla Firefox (Firefox/).Firefoxocre::security::Browser::InternetExplorer(variant): Internet Explorer (MSIE,Trident/).InternetExplorerocre::security::Browser::Opera(variant): Opera (OPR/).Operaocre::security::Browser::Safari(variant): Apple Safari (Version/... Safari/).Safariocre::security::Browser::detect(fn): The browser and its(major, minor)version named by aUser-Agent, orNonefor anything else (bots,curl).pub fn detect(user_agent: &str) -> Option<(Browser, (u32, u32))>- Implements:
Clone,Copy,Debug,Eq,PartialEq
ocre::security::BLOB(const):blob:URLs (files built in the browser).pub const BLOB: &str = "blob:"ocre::security::DATA(const):data:URLs (inline images, fonts).pub const DATA: &str = "data:"ocre::security::FILTERED_PARAMETERS(const): Parameter name fragments whose valuesfilter_parametersandfilter_jsonhide.pub const FILTERED_PARAMETERS: &[&str] = &["passw", "email", "secret", "token", "_key", "crypt", "salt", "certificate", "otp", "ssn", "cvv", "cvc"]ocre::security::HTTPS(const): Anyhttps:URL.pub const HTTPS: &str = "https:"ocre::security::NONCE(const): Placeholder for the request’s nonce: sent as'nonce-<value>'(Rails’content_security_policy_nonce).pub const NONCE: &str = "'nonce'"ocre::security::NONE(const):'none': nothing is allowed, in aContentSecurityPolicysource list.pub const NONE: &str = "'none'"ocre::security::SANITIZE_ATTRIBUTES(const): Attributessanitizekeeps on those tags: Rails’ safe list.pub const SANITIZE_ATTRIBUTES: &[&str] = &[ "abbr", "alt", "cite", "class", "datetime", "height", "href", "lang", "name", "src", "title", "width", "xml:lang", ]ocre::security::SANITIZE_TAGS(const): Tagssanitizekeeps: Rails’ safe list (Rails::HTML5::SafeListSanitizer).pub const SANITIZE_TAGS: &[&str] = &[ "a", "abbr", "acronym", "address", "b", "big", "blockquote", "br", "cite", "code", "dd", "del", "dfn", "div", "dl", "dt", "em", "figcaption", "figure", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "img", "ins", "kbd", "li", "mark", "ol", "p", "pre", "samp", "small", "span", "strike", "strong", "sub", "sup", "time", "tt", "ul", "var", ]ocre::security::SELF(const):'self': the app’s own origin, in aContentSecurityPolicyorPermissionsPolicysource list.pub const SELF: &str = "'self'"ocre::security::STRICT_DYNAMIC(const):'strict-dynamic': scripts loaded by a nonced script are trusted too.pub const STRICT_DYNAMIC: &str = "'strict-dynamic'"ocre::security::UNSAFE_EVAL(const):'unsafe-eval': allowsevalandnew Function(htmx’shx-onandjs:need it).pub const UNSAFE_EVAL: &str = "'unsafe-eval'"ocre::security::UNSAFE_INLINE(const):'unsafe-inline': allows inline<style>/<script>andstyle=attributes.pub const UNSAFE_INLINE: &str = "'unsafe-inline'"
ocre::seo
ocre::seo::json_ld(fn):dataas a JSON-LD<script>for a page’s<head>.pub fn json_ld(data: &impl Serialize) -> Stringocre::seo::LlmsTxt(struct):/llms.txt: a site’s summary and links in Markdown, for language models (https://llmstxt.org).pub struct LlmsTxtocre::seo::LlmsTxt::new(fn): The site’s name (# title) and one-line summary (> summary).pub fn new(title: impl Into<String>, summary: impl Into<String>) -> Selfocre::seo::LlmsTxt::details(fn): Free text after the summary.pub fn details(mut self, text: impl Into<String>) -> Selfocre::seo::LlmsTxt::link(fn): A link in thesectionlist (sections keep the order they first appear in).pub fn link(mut self, section: &str, title: &str, url: &str, description: &str) -> Self- Implements:
Clone,Debug,Default,Display,Eq,IntoResponse,PartialEq
ocre::seo::Sitemap(struct):/sitemap.xml: the pages search engines should crawl.pub struct Sitemapocre::seo::Sitemap::MAX_URLS(const): Most URLs in one sitemap file.pub const MAX_URLS: usize = 50_000ocre::seo::Sitemap::new(fn): An empty sitemap.pub fn new() -> Selfocre::seo::Sitemap::add(fn): Adds a page.pub fn add(&mut self, url: SitemapUrl) -> &mut Selfocre::seo::Sitemap::add_localized(fn): Adds a page in every language:urlsis(hreflang, absolute URL)for each locale, the first being the default (alsox-default).pub fn add_localized(&mut self, urls: &[(&str, &str)], lastmod: Option<&str>) -> &mut Selfocre::seo::Sitemap::len(fn): The URLs added so far.pub fn len(&self) -> usizeocre::seo::Sitemap::is_empty(fn): Whether no URL was added.pub fn is_empty(&self) -> boolocre::seo::Sitemap::to_xml(fn): The sitemap document (UTF-8 XML, values escaped).pub fn to_xml(&self) -> String- Implements:
Clone,Debug,Default,Eq,IntoResponse,PartialEq
ocre::seo::SitemapUrl(struct): A page of aSitemap: its absolute URL, last change and other languages.pub struct SitemapUrlocre::seo::SitemapUrl::loc(field): Absolute URL (https://example.com/fr/pricing).pub loc: Stringocre::seo::SitemapUrl::lastmod(field): Last change,YYYY-MM-DDor a full W3C date-time; omitted whenNone.pub lastmod: Option<String>ocre::seo::SitemapUrl::alternates(field): The page in each language, the page itself included:(hreflang, absolute URL), plus("x-default", url)for the language-picking version.pub alternates: Vec<(String, String)>- Implements:
Clone,Debug,Default,Eq,PartialEq
ocre::sse
ocre::sse::Event(re-export)pub use axum::response::sse::Eventocre::sse::Sse(re-export)pub use axum::response::sse::Sseocre::sse::stream(fn): An event stream:step(state)gives the next event and the next state, orNoneto end the stream.pub fn stream<T, F, Fut>(state: T, step: F) -> Sse<impl Stream<Item = Result<Event, Infallible>> + Send + 'static> where T: Send + 'static, F: FnMut(T) -> Fut + Send + 'static, Fut: Future<Output = Option<(Event, T)>> + Send + 'static
ocre::storage
ocre::storage::analyze(fn): Reads a file’s signature and, for images, its width and height (Active Storage’sanalyze).pub fn analyze(bytes: &[u8]) -> Analysisocre::storage::attach_direct_upload(fn): Finishes a direct upload (or amultipart_uploadsone): checks the object behindsigned_keyagainstrulesand returns itsAttachment.pub fn attach_direct_upload(ctx: &Ctx, field: &str, signed_key: &str, filename: &str, rules: &Rules) -> impl Future<Output = Result<Attachment>> + Send + use<>ocre::storage::check_multipart(fn): Checks the declared file againstrulesand lays it out in parts, asmultipart_uploadsdoes before creating the upload.pub fn check_multipart(field: &str, size: u64, content_type: &str, rules: &Rules, max_part: u64) -> Result<(u64, u16)>ocre::storage::column_changes(fn): Builds the parameters of anUPDATEof one attachment’s columns: a change flag, then the fourcolumns.pub fn column_changes(change: Option<Option<&Attachment>>) -> [Param; 5]ocre::storage::columns(fn): Builds the query parameters for the four columns of one attachment, in column order.pub fn columns(attachment: Option<&Attachment>) -> [Param; 4]ocre::storage::delete(fn): Deletes the object atkey.pub fn delete(ctx: &Ctx, key: &str) -> impl Future<Output = Result<()>> + Send + use<>ocre::storage::delete_attachments(fn): Deletes the objects of everySomeattachment in one R2 call.pub fn delete_attachments(ctx: &Ctx, attachments: &[Option<Attachment>]) -> impl Future<Output = Result<()>> + Send + use<>ocre::storage::direct_upload(fn): Starts a direct upload: checks what the browser declares againstrulesand presigns aPUTof a new key underprefix.pub fn direct_upload(ctx: &Ctx, prefix: &str, field: &str, request: &DirectUploadRequest, rules: &Rules) -> Result<DirectUpload>ocre::storage::direct_upload_script(fn): ServesDIRECT_UPLOAD_JSatGET /ocre/direct-upload.js: merge it into the routes, then load it in the layout with<script src="/ocre/direct-upload.js" defer></script>.pub fn direct_upload_script<S: Clone + Send + Sync + 'static>() -> axum::Router<S>ocre::storage::exists(fn): Returns whether an object exists atkey(Active Storage’sexist?); aheadwithout the details.pub fn exists(ctx: &Ctx, key: &str) -> impl Future<Output = Result<bool>> + Send + use<>ocre::storage::head(fn): Describes the object atkeywithout reading it: size, content type, ETag, upload time;Nonewhen it does not exist.pub fn head(ctx: &Ctx, key: &str) -> impl Future<Output = Result<Option<StoredObject>>> + Send + use<>ocre::storage::human_size(fn): Formats a byte count for people, in powers of 1024 like Rails’number_to_human_size.pub fn human_size(bytes: u64) -> Stringocre::storage::list(fn): Lists one page of the objects whose key starts withprefix, in key order, with their size, type and upload time.pub fn list(ctx: &Ctx, prefix: &str, cursor: Option<&str>, limit: u32) -> impl Future<Output = Result<Listing>> + Send + use<>ocre::storage::multipart_uploads(fn): Routes that upload large files to R2 in parts, resumably (S3 multipart uploads), for thefieldof a form.pub fn multipart_uploads(path: &str, prefix: &'static str, field: &'static str, rules: &'static Rules) -> Router<Ctx>ocre::storage::part_layout(fn): How to cutsizebytes into parts no larger thanmax_part:(part_size, part_count).pub fn part_layout(field: &str, size: u64, max_part: u64) -> Result<(u64, u16)>ocre::storage::presign_get(fn): Presigns aGETof an attachment on R2’s S3 API, validexpires_inseconds (at most 7 days).pub fn presign_get(ctx: &Ctx, attachment: &Attachment, disposition: Disposition, expires_in: u64) -> Result<String>ocre::storage::presign_parts(fn): PresignedPUTURLs ofpartsof the uploadupload_idofkey, validexpires_inseconds.pub fn presign_parts(endpoint: &S3Endpoint, key: &str, upload_id: &str, parts: &[u16], now: i64, expires_in: u64) -> Result<PartUrls>ocre::storage::presign_put(fn): Presigns aPUTof exactlysizebytes of typecontent_typeatkey, validexpires_inseconds.pub fn presign_put(ctx: &Ctx, key: &str, content_type: &str, size: u64, expires_in: u64) -> Result<String>ocre::storage::public_url(fn): The permanent public URL ofkeyin a public bucket:<STORAGE_PUBLIC_URL>/<key>(Active Storage’spublic: true).pub fn public_url(ctx: &Ctx, key: &str) -> Result<String>ocre::storage::purge_unattached(fn): Deletes the objects underprefixolder thanmax_ageseconds that notable.columnrow references, one listing page per call.pub fn purge_unattached(ctx: &Ctx, prefix: &str, table: &str, column: &str, max_age: i64, cursor: Option<&str>) -> impl Future<Output = Result<Purged>> + Send + use<>ocre::storage::read(fn): Reads a whole object into memory, or returnsNonewhenkeydoes not exist.pub fn read(ctx: &Ctx, key: &str) -> impl Future<Output = Result<Option<Vec<u8>>>> + Send + use<>ocre::storage::read_first(fn): Reads the firstlengthbytes of an object (all of it when shorter), orNonewhenkeydoes not exist.pub fn read_first(ctx: &Ctx, key: &str, length: u64) -> impl Future<Output = Result<Option<Vec<u8>>>> + Send + use<>ocre::storage::send_data(fn): Sends bytes built by the handler as a file (Rails’send_data): a CSV export, a generated image, an.icsfile.pub fn send_data(data: impl Into<Bytes>, filename: &str, content_type: &str, disposition: Disposition) -> Responseocre::storage::serve(fn): Streams a stored file to the client, with the headers a browser needs for caching, seeking and saving it.pub fn serve(ctx: &Ctx, attachment: &Attachment, headers: &HeaderMap, disposition: Disposition) -> impl Future<Output = Result<Response>> + Send + use<>ocre::storage::serve_redirect(fn): Answers302 Foundto a presignedGETof the attachment (Active Storage’s redirect mode).pub fn serve_redirect(ctx: &Ctx, attachment: &Attachment, disposition: Disposition, expires_in: u64) -> Result<Response>ocre::storage::store(fn): Stores anUploadin R2 under a new random key starting withprefix, and returns theAttachmentto save.pub fn store(ctx: &Ctx, prefix: &str, upload: Upload) -> impl Future<Output = Result<Attachment>> + Send + use<>ocre::storage::store_body(fn): Streamsbody(exactlysizebytes) into R2 without holding it in memory, and returns itsAttachment.pub fn store_body(ctx: &Ctx, prefix: &str, filename: &str, content_type: &str, size: u64, body: Body) -> impl Future<Output = Result<Attachment>> + Send + use<>ocre::storage::store_bytes(fn): Stores bytes built by the app (a generated report, an export) likestore.pub fn store_bytes(ctx: &Ctx, prefix: &str, filename: &str, content_type: &str, bytes: Vec<u8>) -> impl Future<Output = Result<Attachment>> + Send + use<>ocre::storage::Analysis(struct): Whatanalyzefound in a file’s bytes.pub struct Analysisocre::storage::Analysis::content_type(field): The type told by the file’s signature (magic bytes), orNonefor other files (text, CSV, SVG…).pub content_type: Option<&'static str>ocre::storage::Analysis::width(field): Width in pixels, for PNG, GIF, WebP and JPEG images whose header is in the bytes.pub width: Option<u32>ocre::storage::Analysis::height(field): Height in pixels, likewidth.pub height: Option<u32>- Implements:
Clone,Copy,Debug,Default,Eq,PartialEq
ocre::storage::Attachment(struct): A stored file, as saved with its record in four columns.pub struct Attachmentocre::storage::Attachment::key(field): Object key in the R2 bucket:<prefix>/<22 random URL-safe characters>.pub key: Stringocre::storage::Attachment::filename(field): The uploader’s file name, without directories or control characters.pub filename: Stringocre::storage::Attachment::content_type(field): Content type, lowercase and without parameters (image/png).pub content_type: Stringocre::storage::Attachment::size(field): Size in bytes.pub size: i64ocre::storage::Attachment::human_size(fn): Formats the size for people withhuman_size:512 bytes,2 KB,1.5 MB.pub fn human_size(&self) -> String- Implements:
Clone,Debug,Default,Deserialize,Eq,PartialEq,Serialize
ocre::storage::CompletedPart(struct): A part R2 stored: its number and theETagit answered.pub struct CompletedPartocre::storage::CompletedPart::part_number(field): From 1.pub part_number: u16ocre::storage::CompletedPart::etag(field): The part’sETag, quoted or not.pub etag: String- Implements:
Clone,Debug,Deserialize,Eq,PartialEq,Serialize
ocre::storage::DirectUpload(struct): A direct upload the browser may perform:PUTthe file tourlwithheaders, then submitsigned_key.pub struct DirectUploadocre::storage::DirectUpload::signed_key(field): The object key and its signature (<prefix>/<22 characters>.<43 characters>); the form submits it.pub signed_key: Stringocre::storage::DirectUpload::url(field): PresignedPUTURL on R2’s S3 API.pub url: Stringocre::storage::DirectUpload::headers(field): Headers thePUTmust carry, exactly (Content-Type); the browser addsContent-Lengthitself.pub headers: BTreeMap<String, String>ocre::storage::DirectUpload::sign(fn): Checksrequestagainstrulesand presigns aPUTof a new key underprefix, validexpires_inseconds.pub fn sign(endpoint: &S3Endpoint, prefix: &str, field: &str, request: &DirectUploadRequest, rules: &Rules, now: i64, expires_in: u64) -> Result<Self>- Implements:
Clone,Debug,Deserialize,Eq,PartialEq,Serialize
ocre::storage::DirectUploadRequest(struct): What the browser declares before a direct upload: the file’s name, type and size.pub struct DirectUploadRequestocre::storage::DirectUploadRequest::filename(field): File name, as the browser gives it (cleaned up when attached).pub filename: Stringocre::storage::DirectUploadRequest::content_type(field): Declared content type; signed into the upload URL, so R2 stores this one.pub content_type: Stringocre::storage::DirectUploadRequest::size(field): Declared size in bytes; signed into the upload URL asContent-Length.pub size: u64- Implements:
Clone,Debug,Default,Deserialize,Eq,PartialEq,Serialize
ocre::storage::FinishRequest(struct): The browser finishes (partsset) or abandons an upload.pub struct FinishRequestocre::storage::FinishRequest::signed_key(field): From theMultipartUpload.pub signed_key: Stringocre::storage::FinishRequest::upload_id(field): From theMultipartUpload.pub upload_id: Stringocre::storage::FinishRequest::parts(field): Every part, as R2 answered them; empty to abort.pub parts: Vec<CompletedPart>- Implements:
Clone,Debug,Deserialize,Eq,PartialEq
ocre::storage::Listing(struct): One page oflist: the objects, and the cursor of the next page.pub struct Listingocre::storage::Listing::objects(field): Objects in key order.pub objects: Vec<StoredObject>ocre::storage::Listing::cursor(field): Pass it to the nextlistcall;Noneon the last page.pub cursor: Option<String>- Implements:
Clone,Debug,Default,Deserialize,Eq,PartialEq,Serialize
ocre::storage::Multipart(struct): Extractor for amultipart/form-databody of at mostLIMITbytes.pub struct Multipart<const LIMIT: usize>(pub MultipartForm)- Implements:
Debug,FromRequest
- Implements:
ocre::storage::MultipartForm(struct): The parsed parts of a multipart body: text fields and files, by field name.pub struct MultipartFormocre::storage::MultipartForm::form(fn): Deserializes the text fields intoT, exactly like axum’sForm.pub fn form<T: DeserializeOwned>(&self) -> Result<T>ocre::storage::MultipartForm::text(fn): Returns the first text field namedname, orNonewhen it was not sent.pub fn text(&self, name: &str) -> Option<&str>ocre::storage::MultipartForm::file(fn): Takes the first file sent asname, leaving the others.pub fn file(&mut self, name: &str) -> Option<Upload>ocre::storage::MultipartForm::files(fn): Takes every file sent asnameorname[](an<input type="file" multiple>), in order.pub fn files(&mut self, name: &str) -> Vec<Upload>- Implements:
Clone,Debug,Default,PartialEq
ocre::storage::MultipartUpload(struct): A started multipart upload, sent to the browser.pub struct MultipartUploadocre::storage::MultipartUpload::signed_key(field): The object key and its signature, as for a direct upload: the form submits it.pub signed_key: Stringocre::storage::MultipartUpload::upload_id(field): R2’s id of the upload.pub upload_id: Stringocre::storage::MultipartUpload::part_size(field): Bytes per part; the last part holds the rest.pub part_size: u64ocre::storage::MultipartUpload::part_count(field): Number of parts, numbered from 1.pub part_count: u16- Implements:
Clone,Debug,Deserialize,Eq,PartialEq,Serialize
ocre::storage::PartUrls(struct): Where toPUTeach part:{"urls": {"1": "https://..."}}.pub struct PartUrlsocre::storage::PartUrls::urls(field): Part number to URL: presigned on R2, or a route of the Worker.pub urls: BTreeMap<u16, String>- Implements:
Clone,Debug,Eq,PartialEq,Serialize
ocre::storage::PartsRequest(struct): The browser asks where to send parts:{"signed_key", "upload_id", "parts": [1, 2, 3]}.pub struct PartsRequestocre::storage::PartsRequest::signed_key(field): From theMultipartUpload.pub signed_key: Stringocre::storage::PartsRequest::upload_id(field): From theMultipartUpload.pub upload_id: Stringocre::storage::PartsRequest::parts(field): Part numbers, from 1; at mostMAX_PARTS_PER_REQUEST.pub parts: Vec<u16>- Implements:
Clone,Debug,Deserialize,Eq,PartialEq
ocre::storage::Purged(struct): What onepurge_unattachedcall did: the keys it deleted, and where the next call resumes.pub struct Purgedocre::storage::Purged::deleted(field): Keys deleted by this call.pub deleted: Vec<String>ocre::storage::Purged::cursor(field): Cursor of the next page of the listing;Noneonce the prefix was listed to the end.pub cursor: Option<String>- Implements:
Clone,Debug,Default,Deserialize,Eq,PartialEq,Serialize
ocre::storage::Rules(struct): Describes what a file field accepts: a size limit and a content-type allowlist.pub struct Rulesocre::storage::Rules::max_bytes(field): Largest accepted file, in bytes (u64: multipart uploads take files over 4 GB, more than ausizeholds in WebAssembly).pub max_bytes: u64ocre::storage::Rules::content_types(field): Accepted content types, exact and lowercase (image/png).pub content_types: &'static [&'static str]ocre::storage::Rules::allows(fn): Returns whethercontent_typeis in the allowlist, ignoring case and parameters.pub fn allows(&self, content_type: &str) -> bool- Implements:
Clone,Copy,Debug,Eq,PartialEq
ocre::storage::S3Endpoint(struct): An S3-compatible bucket and the credentials to presign URLs for it.pub struct S3Endpointocre::storage::S3Endpoint::host(field): Host name of the S3 API, without scheme (<account_id>.r2.cloudflarestorage.com).pub host: Stringocre::storage::S3Endpoint::region(field): Signing region:autofor R2.pub region: Stringocre::storage::S3Endpoint::bucket(field): Bucket name, put first in the path (/<bucket>/<key>, path style); empty when the host already names the bucket.pub bucket: Stringocre::storage::S3Endpoint::access_key_id(field): Access key ID of the credentials.pub access_key_id: Stringocre::storage::S3Endpoint::secret_access_key(field): Secret access key of the credentials.pub secret_access_key: Stringocre::storage::S3Endpoint::r2(fn): The S3 endpoint of an R2 bucket: host<account_id>.r2.cloudflarestorage.com, regionauto, path-style URLs.pub fn r2(account_id: &str, bucket: &str, access_key_id: &str, secret_access_key: &str) -> Selfocre::storage::S3Endpoint::presign(fn): Presigns a request onkey(AWS SigV4, query-string form) and returns itshttps://URL.pub fn presign(&self, method: &str, key: &str, headers: &[(&str, &str)], query: &[(&str, &str)], now: i64, expires_in: u64) -> Result<String>- Implements:
Clone,Debug,Eq,PartialEq
ocre::storage::StoredObject(struct): An object in the bucket, asheadandlistdescribe it (without its bytes).pub struct StoredObjectocre::storage::StoredObject::key(field): Object key.pub key: Stringocre::storage::StoredObject::size(field): Size in bytes.pub size: u64ocre::storage::StoredObject::content_type(field): Content type recorded with the object (application/octet-streamwhen none was).pub content_type: Stringocre::storage::StoredObject::etag(field): R2’s entity tag, unquoted (the MD5 of the content for single-part uploads).pub etag: Stringocre::storage::StoredObject::uploaded_at(field): Upload time, in Unix seconds (compare withcrate::now).pub uploaded_at: i64ocre::storage::StoredObject::filename(field): File name recorded bystoreand friends;Nonefor objects uploaded directly.pub filename: Option<String>ocre::storage::StoredObject::attachment(fn): TheAttachmentof this object underfilename(cleaned up), with its recorded size and type.pub fn attachment(&self, filename: &str) -> Attachment- Implements:
Clone,Debug,Default,Deserialize,Eq,PartialEq,Serialize
ocre::storage::Upload(struct): A file received in amultipart/form-datarequest, before it is stored.pub struct Uploadocre::storage::Upload::filename(field): File name sent by the browser, cleaned up.pub filename: Stringocre::storage::Upload::content_type(field): Content type sent by the browser, lowercase without parameters.pub content_type: Stringocre::storage::Upload::bytes(field): The file’s bytes.pub bytes: axum::body::Bytesocre::storage::Upload::new(fn): An upload made by the app (Active Storage’sattach(io:, filename:, content_type:)), cleaned up like a browser’s.pub fn new(filename: &str, content_type: &str, bytes: impl Into<Bytes>) -> Selfocre::storage::Upload::size(fn): Returns the size of the file in bytes.pub fn size(&self) -> u64- Implements:
Clone,Debug,Default,PartialEq
ocre::storage::Variant(struct): A resized version of an image, made by Cloudflare Image Transformations (Active Storage’s variants).pub struct Variantocre::storage::Variant::new(fn): A variant with no resizing: onlyformat=auto.pub const fn new() -> Selfocre::storage::Variant::width(fn): Sets the largest width, in pixels.pub const fn width(mut self, pixels: u32) -> Selfocre::storage::Variant::height(fn): Sets the largest height, in pixels.pub const fn height(mut self, pixels: u32) -> Selfocre::storage::Variant::fit(fn): Sets how the image fits thewidth×heightbox; without it, Cloudflare scales the image down to fit.pub const fn fit(mut self, fit: Fit) -> Selfocre::storage::Variant::quality(fn): Sets the JPEG/WebP/AVIF quality, 1 to 100 (values outside are clamped).pub const fn quality(mut self, quality: u8) -> Selfocre::storage::Variant::path(fn): The same-origin path of this variant ofsource:/cdn-cgi/image/<options>/<source>.pub fn path(&self, source: &str) -> String- Implements:
Clone,Copy,Debug,Default,Eq,PartialEq
ocre::storage::Disposition(enum): Tellsservewhether the browser shows a file or downloads it.pub enum Dispositionocre::storage::Disposition::Inline(variant): Shows the file in the page or tab when its type is safe to display, and downloads anything else.Inlineocre::storage::Disposition::Download(variant): Always downloads the file, with its original name.Download- Implements:
Clone,Copy,Debug,Eq,PartialEq
ocre::storage::Fit(enum): How aVariantfits the image in itswidth×heightbox (Cloudflare’sfitoption).pub enum Fitocre::storage::Fit::ScaleDown(variant): LikeContain, but never enlarges a smaller image (Active Storage’sresize_to_limit).ScaleDownocre::storage::Fit::Contain(variant): Fits inside the box, keeping the aspect ratio (resize_to_fit).Containocre::storage::Fit::Cover(variant): Fills the box, cropping what overflows (resize_to_fill).Coverocre::storage::Fit::Crop(variant): LikeCover, but never enlarges a smaller image.Cropocre::storage::Fit::Pad(variant): LikeContain, then pads to the exact box size (resize_and_pad).Pad- Implements:
Clone,Copy,Debug,Eq,PartialEq
ocre::storage::CACHE_CONTROL(const):Cache-Controlof files sent byserve: browsers keep them but revalidate each time.pub const CACHE_CONTROL: &str = "private, no-cache"ocre::storage::DIRECT_UPLOAD_JS(const): The browser side of direct uploads (Active Storage’sactivestorage.js): a script that sends the files of<input type="file" data-direct-upload-url="...">to R2 before its form is submitted.pub const DIRECT_UPLOAD_JS: &str = include_str!("storage/direct_upload.js")ocre::storage::MAX_EXPIRES_IN(const): Longest lifetime of a presigned URL, in seconds: 7 days, the SigV4 maximum.pub const MAX_EXPIRES_IN: u64 = 604_800ocre::storage::MAX_PART(const): Largest part R2 accepts: 5 GiB.pub const MAX_PART: u64 = 5 * 1024 * MIBocre::storage::MAX_PARTS(const): Most parts in one upload.pub const MAX_PARTS: u64 = 10_000ocre::storage::MAX_PARTS_PER_REQUEST(const): Most part URLs answered at once.pub const MAX_PARTS_PER_REQUEST: usize = 1_000ocre::storage::MAX_WORKER_PART(const): Largest part sent through the Worker (its request limit is 100 MB).pub const MAX_WORKER_PART: u64 = 95 * MIBocre::storage::PART_SIZE(const): Size of the parts: 10 MiB, or more for a file that would need over 10,000.pub const PART_SIZE: u64 = 10 * MIBocre::storage::R2_ACCESS_KEY_ID(const): Worker secret holding the access key ID of an R2 API token, for presigned R2 URLs.pub const R2_ACCESS_KEY_ID: &str = "R2_ACCESS_KEY_ID"ocre::storage::R2_ACCOUNT_ID(const): Worker variable holding the Cloudflare account ID, for presigned R2 URLs.pub const R2_ACCOUNT_ID: &str = "R2_ACCOUNT_ID"ocre::storage::R2_BUCKET(const): Worker variable holding the R2 bucket name (<app>-storage), for presigned R2 URLs.pub const R2_BUCKET: &str = "R2_BUCKET"ocre::storage::R2_SECRET_ACCESS_KEY(const): Worker secret holding the secret access key of an R2 API token, for presigned R2 URLs.pub const R2_SECRET_ACCESS_KEY: &str = "R2_SECRET_ACCESS_KEY"ocre::storage::STORAGE_BINDING(const): Name of the R2 binding holding every file:STORAGE: bindings.r2({ name: "<app>-storage" })in cloudflare.config.ts.pub const STORAGE_BINDING: &str = "STORAGE"ocre::storage::STORAGE_PUBLIC_URL(const): Name of the Worker variable holding the base URL of a public bucket, forpublic_url.pub const STORAGE_PUBLIC_URL: &str = "STORAGE_PUBLIC_URL"
ocre::testing (feature testing)
ocre::testing::block_on(re-export): Runs a future to completion on the test thread:asynchandlers, helpers andocre::passwordin plain unit tests (no async runtime runs outside workerd).pub use pollster::block_onocre::testing::assert_changes(fn): Asserts thatblockchanges whatexpressionreturns (Rails’assert_changes), and returns(before, after).pub fn assert_changes<T: PartialEq + Debug>(mut expression: impl FnMut() -> T, block: impl FnOnce()) -> (T, T)ocre::testing::assert_difference(fn): Asserts thatblockchanges the numberexpressionreturns bydifference(Rails’assert_difference), and returns the block’s value.pub fn assert_difference<R>(mut expression: impl FnMut() -> i64, difference: i64, block: impl FnOnce() -> R) -> Rocre::testing::assert_no_changes(fn): Asserts thatblockleaves whatexpressionreturns unchanged (Rails’assert_no_changes).pub fn assert_no_changes<T: PartialEq + Debug>(mut expression: impl FnMut() -> T, block: impl FnOnce())ocre::testing::assert_no_difference(fn): Asserts thatblockleaves the numberexpressionreturns unchanged (Rails’assert_no_difference).pub fn assert_no_difference<R>(expression: impl FnMut() -> i64, block: impl FnOnce() -> R) -> Rocre::testing::count(fn): Number of rows oftablein the test database, forassert_difference.pub fn count(table: &str) -> i64ocre::testing::eventually(fn): Retriescheckevery 100 ms for up to 30 seconds until it returnsSome, for effects that happen later: a queued job, a cron, a broadcast.pub fn eventually<T>(check: impl FnMut() -> Option<T>) -> Tocre::testing::fixture(fn): The row oftableloaded from the fixturelabel(Rails’posts(:first)).pub fn fixture(table: &str, label: &str) -> Map<String, Value>ocre::testing::fixture_id(fn): Theidof the fixture labelledlabel(Rails’users(:david).id): the loader oftests/fixtures/*.ymlgives a record without an explicitidthe CRC-32 of its label modulo 2^30 - 1, like Rails.pub fn fixture_id(label: &str) -> i64ocre::testing::freeze_time(fn): Stopscrate::nowat the current second (Rails’freeze_time); returns it.pub fn freeze_time() -> i64ocre::testing::insert(fn): Inserts a row intotableof the test database and returns itsid: what generated factories (tests/factories/) call.pub fn insert(table: &str, values: &[(&str, Value)]) -> i64ocre::testing::quote(fn):valueas a SQL literal: strings quoted ('doubled), numbers as is, booleans as1/0, null asNULL, arrays and objects as JSON text.pub fn quote(value: impl Into<Value>) -> Stringocre::testing::redact(fn): Replaces values that change on every run by placeholders, so a snapshot or anassert_eq!on a whole page or JSON body is stable (Loco’scleanup_*filters): UUIDs become<UUID>, ISO 8601 dates and times (2026-01-01,2026-01-01T12:00:00Z,2026-01-01 12:00:00) become<DATE>, and runs of 32 or more hexadecimal or base64url characters (tokens, digests) become<TOKEN>.pub fn redact(text: &str) -> Stringocre::testing::sequence(fn): A unique number per call in the test process, for unique test data (FactoryBot’ssequence): 1, 2, 3…pub fn sequence() -> u64ocre::testing::sql(fn): Rows returned byquery, run on the test database (Rails’ActiveRecord::Base.connection.select_all).pub fn sql(query: &str) -> Vec<Map<String, Value>>ocre::testing::travel(fn): Movescrate::nowbysecondsfrom its current value and freezes it there (Rails’travel 1.day).pub fn travel(seconds: i64)ocre::testing::travel_back(fn): Returnscrate::nowto the real clock (Rails’travel_back).pub fn travel_back()ocre::testing::travel_to(fn): Makescrate::nowreturnunixon this thread untiltravel_back(Rails’travel_to, frozen).pub fn travel_to(unix: i64)ocre::testing::var(fn): A variable of the app under test: the environment variablename, else its value in.dev.vars(the fileocre devloads), as the Worker sees it.pub fn var(name: &str) -> Option<String>ocre::testing::Broadcast(struct): A message broadcast to a realtime channel, fromClient::broadcasts.pub struct Broadcastocre::testing::Broadcast::id(field): Position in the capture, from 1.pub id: u64ocre::testing::Broadcast::channel(field): The channel it went to (posts).pub channel: Stringocre::testing::Broadcast::message(field): The message: HTML or JSON text.pub message: String- Implements:
Clone,Debug,Deserialize,Eq,PartialEq
ocre::testing::Client(struct): An HTTP client for request tests, with a cookie jar, like a browser tab (Rails’ integration session).pub struct Clientocre::testing::Client::new(fn): A client for the serverocre test --e2estarted (TEST_URL).pub fn new() -> Selfocre::testing::Client::with_base_url(fn): A client for the app atbase(http://localhost:8787), e.g. a runningocre dev.pub fn with_base_url(base: &str) -> Selfocre::testing::Client::header(fn): Sendsname: valuewith every request (Rails’headers:); replaces an earlier value of the same header.pub fn header(mut self, name: &str, value: &str) -> Selfocre::testing::Client::cross_site(fn): Requests as a form posted from another site would (Sec-Fetch-Site: cross-site): Ocre’s CSRF protection answers 403 to unsafe methods.pub fn cross_site(self) -> Selfocre::testing::Client::htmx(fn): Requests as htmx does (HX-Request: true), Rails’xhr: true.pub fn htmx(self) -> Selfocre::testing::Client::get(fn):GET path.pub fn get(&mut self, path: &str) -> Responseocre::testing::Client::post(fn):POST pathwith anapplication/x-www-form-urlencodedbody, as an HTML form sends it.pub fn post(&mut self, path: &str, form: &impl Serialize) -> Responseocre::testing::Client::post_json(fn):POST pathwithvalueas a JSON body.pub fn post_json(&mut self, path: &str, value: &impl Serialize) -> Responseocre::testing::Client::patch_json(fn):PATCH pathwithvalueas a JSON body.pub fn patch_json(&mut self, path: &str, value: &impl Serialize) -> Responseocre::testing::Client::put_json(fn):PUT pathwithvalueas a JSON body.pub fn put_json(&mut self, path: &str, value: &impl Serialize) -> Responseocre::testing::Client::delete(fn):DELETE path.pub fn delete(&mut self, path: &str) -> Responseocre::testing::Client::request(fn): Sendsmethod pathwith an optional(content type, body): any method, any body (multipart uploads, raw bytes).pub fn request(&mut self, method: &str, path: &str, body: Option<(&str, Vec<u8>)>) -> Responseocre::testing::Client::follow_redirect(fn): Follows the redirectresponseanswered:GETof itsLocation(Rails’follow_redirect!).pub fn follow_redirect(&mut self, response: &Response) -> Responseocre::testing::Client::cookie(fn): The cookienameas the server set it (percent-encoded), if the jar has it.pub fn cookie(&self, name: &str) -> Option<&str>ocre::testing::Client::set_cookie(fn): Sets a cookie sent with the next requests, as if the server had set it.pub fn set_cookie(&mut self, name: &str, value: &str)ocre::testing::Client::session(fn): The session data (Rails’sessionin tests), decrypted with the app’sSECRET_KEY_BASE(the environment variable, else.dev.vars): empty without a session cookie.pub fn session(&self) -> Map<String, Value>ocre::testing::Client::flash(fn): The flash message ofkind(notice,alert…) set by the last request for the next page (Rails’flash[:notice]after an action).pub fn flash(&self, kind: &str) -> Option<String>ocre::testing::Client::deliveries(fn): Emails the app sent withMAIL_ADAPTER = "log"(Rails’ActionMailer::Base.deliveries), oldest first: the last 20, kept by the Worker instance.pub fn deliveries(&mut self) -> Vec<Email>ocre::testing::Client::broadcasts(fn): Messages the app broadcast to realtime channels (Rails’assert_broadcasts), oldest first: the last 50, kept by the Worker instance.pub fn broadcasts(&mut self) -> Vec<Broadcast>ocre::testing::Client::jobs(fn): Jobs the app enqueued and ran (Rails’assert_enqueued_with,assert_performed_jobs): the last 50 of each, oldest first, kept by the Worker instance.pub fn jobs(&mut self) -> Jobsocre::testing::Client::receive_email(fn): Delivers an email to the app’s mailbox (ocre g mailbox), as Cloudflare Email Routing would (Rails’receive_inbound_email_from_mail): a plain-text message posted to the local server’s email endpoint (POST /cdn-cgi/local/email?from=&to=), which runs the Worker’semailevent.pub fn receive_email(&mut self, from: &str, to: &str, subject: &str, body: &str) -> Response- Implements:
Debug
ocre::testing::EnqueuedJob(struct): A job sent to a queue, fromClient::jobs.pub struct EnqueuedJobocre::testing::EnqueuedJob::id(field): Position in the capture, from 1 (shared with runs).pub id: u64ocre::testing::EnqueuedJob::queue(field): The queue:default, or the name given toocre::jobs::queue.pub queue: Stringocre::testing::EnqueuedJob::job(field): The job as the app serialized it:{"send_welcome": {"user_id": 7}}.pub job: Valueocre::testing::EnqueuedJob::name(fn): The job’s name: the key of its JSON object (send_welcome), asPerformedJob::jobnames it.pub fn name(&self) -> Option<&str>- Implements:
Clone,Debug,Deserialize,PartialEq
ocre::testing::Jobs(struct): Jobs the app enqueued and ran, fromClient::jobs.pub struct Jobsocre::testing::Jobs::enqueued(field): Jobs sent to a queue, oldest first.pub enqueued: Vec<EnqueuedJob>ocre::testing::Jobs::performed(field): Jobs the queue consumer ran, oldest first.pub performed: Vec<PerformedJob>- Implements:
Clone,Debug,Default,Deserialize,PartialEq
ocre::testing::Log(struct): The test server’s log (cf devoutput:console.log, job and cron lines, errors), read from the position ofLog::markon.pub struct Logocre::testing::Log::mark(fn): The log from now on (TEST_LOG, else.wrangler/test-state/dev.log).pub fn mark() -> Selfocre::testing::Log::text(fn): What was logged since the mark.pub fn text(&self) -> Stringocre::testing::Log::wait_for(fn): Waits up to 30 seconds for a line containingneedleand returns it.pub fn wait_for(&self, needle: &str) -> String- Implements:
Clone,Debug
ocre::testing::PerformedJob(struct): A job run by the queue consumer, fromClient::jobs.pub struct PerformedJobocre::testing::PerformedJob::id(field): Position in the capture, from 1 (shared with enqueued jobs).pub id: u64ocre::testing::PerformedJob::job(field): The job’s name (send_welcome), ormailfordeliver_lateremails.pub job: Stringocre::testing::PerformedJob::outcome(field):done,discarded(an error a retry cannot fix) orretried.pub outcome: String- Implements:
Clone,Debug,Deserialize,Eq,PartialEq
ocre::testing::Response(struct): A response in a request test, with chainable assertions (Rails’assert_response,assert_redirected_to,assert_match).pub struct Responseocre::testing::Response::status(field): HTTP status code.pub status: u16ocre::testing::Response::headers(field): Headers in the order received, names lowercase.pub headers: Vec<(String, String)>ocre::testing::Response::body(field): Body as text (invalid UTF-8 replaced); empty forHEAD, 204 and 304.pub body: Stringocre::testing::Response::header(fn): The first value of the headername(any case).pub fn header(&self, name: &str) -> Option<&str>ocre::testing::Response::location(fn): TheLocationheader of a redirect.pub fn location(&self) -> Option<&str>ocre::testing::Response::json(fn): The body parsed as JSON (Rails’response.parsed_body).pub fn json<T: DeserializeOwned>(&self) -> Tocre::testing::Response::assert_status(fn): Asserts the status code (Rails’assert_response 201).pub fn assert_status(&self, status: u16) -> &Selfocre::testing::Response::assert_success(fn): Asserts a 2xx status (Rails’assert_response :success).pub fn assert_success(&self) -> &Selfocre::testing::Response::assert_redirect_to(fn): Asserts a 3xx redirect tolocation(Rails’assert_redirected_to).pub fn assert_redirect_to(&self, location: &str) -> &Selfocre::testing::Response::assert_contains(fn): Asserts the body containstext(HTML-escaped as templates escape it:'is').pub fn assert_contains(&self, text: &str) -> &Selfocre::testing::Response::assert_not_contains(fn): Asserts the body does not containtext.pub fn assert_not_contains(&self, text: &str) -> &Selfocre::testing::Response::assert_header(fn): Asserts the headernamehasvalue.pub fn assert_header(&self, name: &str, value: &str) -> &Self- Implements:
Clone,Debug
ocre::testing::TEST_LOG(const): Environment variable holding the path of the test server’s log.pub const TEST_LOG: &str = "OCRE_TEST_LOG"ocre::testing::TEST_STATE(const): Environment variable holding the local state directory of the test run (.wrangler/test-state).pub const TEST_STATE: &str = "OCRE_TEST_STATE"ocre::testing::TEST_URL(const): Environment variable holding the base URL of the serverocre test --e2estarted.pub const TEST_URL: &str = "OCRE_TEST_URL"
ocre::token
ocre::token::constant_time_eq(fn): Whetheraequalsb, compared in constant time for equal lengths.pub fn constant_time_eq(a: &[u8], b: &[u8]) -> boolocre::token::digest(fn): SHA-256 oftokenas 64 lowercase hex characters: the value to store and look up.pub fn digest(token: &str) -> Stringocre::token::generate(fn): A new random token:TOKEN_BYTESsecure random bytes as URL-safe base64 without padding (43 characters).pub fn generate() -> Stringocre::token::public_id(fn): A random id for URLs: 22 URL-safe characters (128 bits), the value of apublic_id:tokencolumn.pub fn public_id() -> Stringocre::token::TOKEN_BYTES(const): Random bytes in a token generated bygenerate: 32 (256 bits).pub const TOKEN_BYTES: usize = 32
ocre::webhooks
ocre::webhooks::once(fn): Runseffectfor the eventevent_idofsourceunless it already ran.pub async fn once<T, F, Fut>(db: &Db, source: &str, event_id: &str, payload: &[u8], effect: F) -> Result<Delivery<T>> where F: FnOnce() -> Fut, Fut: Future<Output = Result<T>>ocre::webhooks::post_signed(fn): POSTsbodyas JSON tourl, signed: the HMAC-SHA256 of the body withsecretinX-Signature(lowercase hex, seesign), andAuthorization: Bearer <bearer>when given (API keys of services such as RunPod).pub fn post_signed(url: &str, secret: &[u8], bearer: Option<&str>, body: &serde_json::Value) -> impl Future<Output = Result<Answer>> + Send + use<>ocre::webhooks::sign(fn): HMAC-SHA256 ofmessagewithsecret, as lowercase hex: the signature to send in a header (X-Signature) of an outgoing call.pub fn sign(secret: &[u8], message: &[u8]) -> Stringocre::webhooks::sign_standard(fn): Thewebhook-signatureheader value (v1,<base64>) of a Standard Webhooks delivery ofbodywith thisidandtimestamp(Unix seconds): whatverify_standardchecks.pub fn sign_standard(secret: &str, id: &str, timestamp: i64, body: &[u8]) -> Result<String>ocre::webhooks::verify(fn): Checks thatsignatureis the HMAC-SHA256 ofmessagewithsecret, in constant time.pub fn verify(secret: &[u8], message: &[u8], signature: &str) -> Result<()>ocre::webhooks::verify_standard(fn): Checks a Standard Webhooks delivery (Svix, Resend, and other providers):webhook-signatureholds one or more space-separatedv1,<base64>signatures of{id}.{timestamp}.{body}keyed with the base64 part of thewhsec_...secret, and thewebhook-timestampmust be withintoleranceseconds ofnow(replays of an old delivery are refused).pub fn verify_standard(secret: &str, headers: &axum::http::HeaderMap, body: &[u8], tolerance: i64, now: i64) -> Result<String>ocre::webhooks::Answer(struct): The answer ofpost_signed: status and body.pub struct Answerocre::webhooks::Answer::status(field): HTTP status.pub status: u16ocre::webhooks::Answer::text(field): Body, as text.pub text: String- Implements:
Clone,Debug,Eq,PartialEq
ocre::webhooks::Delivery(enum): Whatoncedid with a delivery.pub enum Delivery<T>ocre::webhooks::Delivery::Processed(variant): The effect ran (first delivery, or a retry after a failure) and returned this.Processed(T)ocre::webhooks::Delivery::Duplicate(variant): Already processed, or being processed by another invocation: nothing ran.Duplicate- Implements:
Clone,Debug,Eq,PartialEq
ocre::webhooks::STALE_AFTER(const): A delivery leftprocessingthis long (seconds) is taken over by the next one: the invocation that claimed it died before finishing.pub const STALE_AFTER: i64 = 300ocre::webhooks::TABLE_SQL(const): Thewebhook_eventstableoncerecords deliveries in, created by the migration ofocre g webhook.pub const TABLE_SQL: &str = "CREATE TABLE webhook_events (id INTEGER PRIMARY KEY, source TEXT NOT NULL, event_id TEXT NOT NULL, payload TEXT NOT NULL, status TEXT NOT NULL, attempts INTEGER NOT NULL DEFAULT 1, error TEXT, received_at INTEGER NOT NULL, processed_at INTEGER, UNIQUE (source, event_id))