Skip to main content

Engine

Struct Engine 

Source
pub struct Engine { /* private fields */ }
Expand description

JSONLogic compile/evaluate engine.

Holds the immutable engine state — registered crate::CustomOperator implementations, the EvaluationConfig, the templating, folding and family settings — and exposes the public surface for parsing rules (Self::compile), evaluating them (Self::eval / Self::eval_str, Self::eval_into), and opening hot-loop sessions (Self::session). Enabling the trace feature also exposes Self::trace for traced sessions.

Engine is Send + Sync (every field is); the typical pattern is to build one at startup, wrap it in Arc<Engine>, and clone the Arc across threads or async tasks.

§Example

use datalogic_rs::Engine;

// 1. Build the engine.
let engine = Engine::new();

// 2. Compile a rule once.
let logic = engine
    .compile(r#"{"if": [{">=": [{"var": "age"}, 18]}, "adult", "minor"]}"#)
    .unwrap();

// 3. Evaluate against many inputs (here via `Session::eval_str`;
//    drop to `Engine::evaluate` if you want zero-copy borrowed results).
let mut session = engine.session();
for age in [12, 18, 42] {
    let payload = format!(r#"{{"age": {age}}}"#);
    let result = session.eval_str(&logic, &payload).unwrap();
    assert!(result == "\"adult\"" || result == "\"minor\"");
    session.reset();
}

§Choosing an evaluate method

Start here. Use Self::eval_str for one-shot calls. Switch to crate::Session once you’re evaluating the same compiled rule many times — it reuses one arena instead of allocating per call. Drop down to Self::evaluate only when you’re managing your own bumpalo::Bump (custom pools, integration with arena-aware downstream code).

Result-shape suffixes work the same on every tier: (none) returns datavalue::OwnedDataValue, _str returns String (JSON), _into::<T> returns T: DeserializeOwned (requires serde_json). The raw Self::evaluate is the only method that exposes &'a DataValue<'a> and a caller-owned &Bump.

Three tiers, in order of caller control:

MethodArena ownershipResult typeWhen to use
Self::eval / Self::eval_str / Self::eval_intoengine creates a fresh Bump::with_capacity(4096) per callOwnedDataValue / String / TOne-shot. Any caller that doesn’t want to think about arenas. Allocates each call — for hot loops, drop to Session.
crate::Session::eval / crate::Session::eval_str / crate::Session::eval_into / crate::Session::eval_borrowedsession-owned Bump, caller calls crate::Session::reset between batchesowned / String / T / borrowed &'a DataValue<'a>Hot loop with a long-lived engine. The Session hides bumpalo from the call site and pre-sizes the arena via crate::Session::reset_with_capacity when needed.
Self::evaluatecaller-passed &Bump; library never resets&'a DataValue<'a> (borrowed)Zero-copy result paths, custom pool/allocator strategies, integration with arena-aware downstream code.

All routes share the same dispatcher; the differences are who owns the arena, what the result type looks like, and whether the boundary parses / serialises JSON for you. There is no perf difference between the arena-aware paths once the bump is warm.

See the crate-level docs for the two-phase architecture, threading model, and walk-through examples; see the Session and EvaluationConfig rustdoc for arena-management and behaviour-tuning options respectively.

Implementations§

Source§

impl Engine

Source

pub fn builder() -> EngineBuilder

Start a crate::EngineBuilder for fluent construction.

Use the builder when you need a non-default EvaluationConfig, templating mode, or pre-registered custom operators. For a stock engine, Self::new is shorter.

Source

pub fn to_builder(&self) -> EngineBuilder

A builder that starts from this engine: the same custom operators, config, templating mode, template key escape and folding setting. Change what differs and call build for a new engine; this one is untouched.

Both engines share each operator instance (and any state it holds), so a host that rebuilds on every reload does not register its operators again. Rules compiled on this engine still evaluate on the new one, looking their custom operators up by name.

§Example
use datalogic_rs::{Engine, EvaluationConfig, MissingVar};

let running = Engine::new();
let reloaded = running
    .to_builder()
    .with_config(EvaluationConfig::default().with_missing_var(MissingVar::Error))
    .build();
assert!(reloaded.eval_str(r#"{"var": "x"}"#, "{}").is_err());
assert_eq!(running.eval_str(r#"{"var": "x"}"#, "{}").unwrap(), "null");
Source

pub fn session(&self) -> Session<'_>

Open a crate::Session handle that owns a reusable arena and returns owned results, so callers don’t need to manage a bumpalo::Bump themselves.

Use this when you want the throughput of arena reuse without the lifetime juggling of Self::evaluate. Results are deep-cloned out of the arena before returning, so they survive later calls and resets. The session does not auto-reset: allocations accumulate until you call crate::Session::reset, which you should do between logical batches to bound peak memory in long-running services.

§Example
use datalogic_rs::Engine;

let engine = Engine::new();
let compiled = engine.compile(r#"{"+": [{"var": "x"}, 1]}"#).unwrap();
let mut session = engine.session();
let result = session.eval_str(&compiled, r#"{"x": 41}"#).unwrap();
assert_eq!(result, "42");
Source

pub fn new() -> Self

Creates a new Engine with all built-in operators.

The engine includes every built-in operator compiled into this build (84 canonical operators with all operator features on; see Self::builtin_operator_names), dispatched via OpCode. Templating mode is disabled by default. For non-default configuration (custom EvaluationConfig, templating mode, pre-registered custom operators) prefer Self::builder.

§Example
use datalogic_rs::Engine;

let engine = Engine::new();
Source

pub fn config(&self) -> &EvaluationConfig

Gets a reference to the current evaluation configuration.

Source

pub fn has_custom_operator(&self, name: &str) -> bool

Checks if a custom operator with the given name is registered.

Operator registration is builder-only; this is a read-only check against the frozen set produced by crate::EngineBuilder.

Source

pub fn custom_operator_info(&self, name: &str) -> Option<CustomOperatorInfo>

What the custom operator registered as name declares about itself (crate::CustomOperator::info), or None when no custom operator has that name. Built-ins are described by Self::operators.

Source

pub fn custom_operator_names(&self) -> impl Iterator<Item = &str>

Iterator over the names of every custom operator registered on this engine (built-ins are not included). Order is unspecified (HashMap iteration order). Useful for tooling, UIs, and tests that need to introspect what’s available.

Source

pub fn builtin_operator_names( &self, ) -> impl Iterator<Item = &'static str> + use<>

Iterator over every built-in operator name this build evaluates: the JSONLogic baseline plus whichever extension families (ext-string, datetime, ext-control, …) were compiled in.

The list is derived from the same table the compiler resolves operator keys against, so it cannot drift from dispatch. It includes input aliases (var for val, ?: for if, match for switch) because those keys are live calls too; order is canonical name first, then its aliases, per operator.

Custom registrations are not included; see Self::custom_operator_names. The union of the two is the full vocabulary of this engine. A custom operator registered under a built-in name is never reached: built-in resolution wins at compile time.

Under templating mode an unknown key is not an error (the object echoes back as data), so this is the vocabulary authoring-side tooling needs to tell a live call from a literal.

§Example
use datalogic_rs::Engine;

let engine = Engine::new();
let names: Vec<&str> = engine.builtin_operator_names().collect();
assert!(names.contains(&"val"));
assert!(names.contains(&"var")); // alias of `val`
assert!(!names.contains(&"lenght"));
Source

pub fn operators(&self) -> impl Iterator<Item = OperatorInfo> + use<>

Every built-in operator compiled into this build, described by its operator-table row: name and aliases, family and gating feature, declared argument counts, whether it reads the data context, its effect, its cost class, and which argument (if any) runs under a pushed frame.

Read from the same table that drives compilation, dispatch and the optimizer, so it cannot drift from what the engine does. Custom operators are not included; see Self::custom_operator_names.

§Example
use datalogic_rs::{Engine, ScopedArg};

let engine = Engine::new();
let map = engine.operators().find(|op| op.name == "map").unwrap();
assert_eq!(map.family, "Core");
assert_eq!(map.feature, None);
assert_eq!(map.scoped_arg, Some(ScopedArg::Index(1)));

let val = engine.operators().find(|op| op.name == "val").unwrap();
assert_eq!(val.aliases, ["var"]);
assert!(val.reads_context);
Source

pub fn compile<R: IntoLogic>(&self, rule: R) -> Result<Logic>

Compile a rule source into reusable Logic.

rule accepts any crate::IntoLogic shape: &str (JSON-parsed), &OwnedDataValue / OwnedDataValue (cloned/moved), or &serde_json::Value (gated on serde_json). For cross-thread sharing prefer Self::compile_arc.

§Example
use datalogic_rs::Engine;

let engine = Engine::new();
let compiled = engine.compile(r#"{"==": [{"var": "x"}, 1]}"#).unwrap();
Source

pub fn check<R: IntoLogic>(&self, rule: R, mode: CheckMode) -> Vec<Diagnostic>

Check rule without compiling it: every problem the engine can see before it runs, in rule order, each located by a JSON Pointer.

An Error is something that will fail: a rule that does not compile (an object with several keys outside templating mode), or a call that fails whenever it runs (an unknown operator, and / or / if without an argument array, an argument count the operator rejects, a literal timezone that does not exist). A Warning runs, but probably not as meant: arguments an operator never evaluates, or in a template an output key one edit away from an operator name.

Unlike Self::compile, which stops at the first problem and leaves call errors to evaluation, this reports them all, including those in branches a given input never reaches. mode chooses strict or templating mode for this check (see crate::CheckMode).

§Example
use datalogic_rs::{CheckMode, DiagnosticCode, Engine};

let engine = Engine::new();
let diags = engine.check(r#"{"if": [true, {"vr": "x"}, {"map": [1]}]}"#, CheckMode::Engine);
assert_eq!(diags.len(), 2);
assert_eq!(diags[0].code, DiagnosticCode::UnknownOperator);
assert_eq!(diags[0].pointer, "/if/1");
assert!(diags[0].message.contains("did you mean `var`"));
assert_eq!(diags[1].code, DiagnosticCode::ArgumentCount);
Source

pub fn compile_checked<R: IntoLogic>( &self, rule: R, ) -> Result<Logic, CompileError>

Self::compile, refusing a rule that Self::check finds any error in: strict up front, where compile leaves a call that cannot succeed to fail at evaluation. The error carries every diagnostic, warnings included. A rule with only warnings compiles.

§Errors

crate::CompileError listing the diagnostics.

Source

pub fn compile_template<R: IntoLogic>(&self, rule: R) -> Result<Logic>

Available on crate feature templating only.

Compile rule in templating mode, whatever mode the engine was built with: a multi-key object is an output template and an unknown operator key is an output field, as on an engine built with_templating(true). The engine’s custom operators, template key escape and folding setting apply as usual.

With Self::compile_strict this lets one engine, with one set of custom operators, both check rules strictly and compile output templates, instead of a host building an engine per mode.

§Example
use datalogic_rs::Engine;

let engine = Engine::new();
let template = r#"{"user": {"var": "name"}, "source": "api"}"#;
assert!(engine.compile(template).is_err());

let logic = engine.compile_template(template).unwrap();
let out = engine.session().eval_str(&logic, r#"{"name": "ana"}"#).unwrap();
assert_eq!(out, r#"{"user":"ana","source":"api"}"#);
Source

pub fn compile_strict<R: IntoLogic>(&self, rule: R) -> Result<Logic>

Compile rule outside templating mode, whatever mode the engine was built with: a multi-key object is an error, and an unknown operator is not an output field, exactly as on an engine built without templating. The engine’s custom operators and folding setting apply as usual.

On an engine built without templating this is Self::compile.

§Example
use datalogic_rs::Engine;

let engine = Engine::builder().with_templating(true).build();
let typo = r#"{"user": {"var": "name"}, "sourec": "api"}"#;
assert!(engine.compile(typo).is_ok());          // an output template
assert!(engine.compile_strict(typo).is_err());  // not a rule
Source

pub fn compile_arc<R: IntoLogic>(&self, rule: R) -> Result<Arc<Logic>>

Compile and wrap in an Arc in one call. Convenience for the dominant cross-thread-sharing pattern; equivalent to Arc::new(engine.compile(rule)?).

Source

pub fn trace(&self) -> TracedSession<'_>

Available on crate feature trace only.

Open a crate::TracedSession over this engine. Calls made through the session collect a per-call trace; the bare eval* methods on Engine itself pay no trace overhead.

Available only when the crate is built with feature = "trace".

§Trace coverage

The session’s one-shot crate::TracedSession::eval_str compiles the rule internally with optimization disabled, so every operator in the rule surfaces a trace step.

The pre-compiled paths (crate::TracedSession::eval taking a &Logic) inherit whatever shape that Logic was compiled into — constant sub-expressions folded by Self::compile won’t appear, since there is no operator left to execute. Use eval_str for full coverage on a one-shot run.

§Example
use datalogic_rs::Engine;

let engine = Engine::new();
let run = engine
    .trace()
    .eval_str(r#"{"+": [1, 2]}"#, "null");
assert_eq!(run.result.unwrap(), "3");
// run.steps is the per-node execution log;
// run.expression_tree is the rule's compile-time tree shape.
Source

pub fn evaluate<'a, D: EvalInput<'a>>( &self, compiled: &'a Logic, data: D, arena: &'a Bump, ) -> Result<&'a DataValue<'a>>

Evaluate compiled logic against arena-resident data — raw tier.

The caller owns the bumpalo::Bump lifecycle and may reset() it between calls; the returned &DataValue<'a> borrows from the arena, so it must be dropped before the next reset (enforced by the borrow checker). For ergonomic owned/typed/JSON-string output, prefer Self::eval / Self::eval_str / Self::eval_into.

§Example
use bumpalo::Bump;
use datalogic_rs::{Engine, DataValue};

let engine = Engine::new();
let compiled = engine.compile(r#"{"+": [{"var": "x"}, 2]}"#).unwrap();

let arena = Bump::new();
let data = DataValue::from_str(r#"{"x": 40}"#, &arena).unwrap();
let result = engine.evaluate(&compiled, data, &arena).unwrap();
assert_eq!(result.as_i64(), Some(42));

data accepts any input shape understood by crate::EvalInput: &'a DataValue<'a> (zero-cost passthrough), DataValue<'a> (single arena alloc), &str (JSON-parsed), &OwnedDataValue (deep-borrowed), &ParsedData (zero-cost passthrough of a parse-once handle), or &serde_json::Value (gated on serde_json).

Source

pub fn resolve_ops_budget(&self, explicit: Option<u64>) -> u64

Available on crate feature budget only.

The budget a metered call runs under: explicit when the caller gave one, else the engine-wide EvaluationConfig::ops_budget, else unbounded (u64::MAX).

This is the precedence Self::evaluate applies implicitly, made available to callers of Self::evaluate_metered — the language bindings’ “omit the budget to use the engine’s” forms all resolve through here, so a rule metered from any of them reports the same number.

Source

pub fn evaluate_metered<'a, D: EvalInput<'a>>( &self, compiled: &'a Logic, data: D, arena: &'a Bump, budget: u64, ) -> Result<Metered<&'a DataValue<'a>>>

Available on crate feature budget only.

Evaluate under an explicit operation budget, reporting what the evaluation spent.

Same evaluation as Self::evaluate, with two differences: the budget argument overrides EvaluationConfig::ops_budget for this call, and the result carries the operation count next to the value. Pass u64::MAX to meter without bounding.

§What the count means

“Nodes dispatched at runtime, plus whatever operators charge” — not “nodes in the source”. Concretely:

  • 1 per dispatched node. Literals cost 0 (they return before dispatch), and so do constant-folded subtrees — the compiler already did that work, and charging for it would make the count depend on whether folding was enabled.
  • 1 per item an iterator examines, charged by map, filter, reduce, the quantifiers, sort and friends as soon as the source is resolved. This is what keeps the number honest when a compile-time fast path evaluates a predicate inline instead of dispatching its body: the iteration costs at least its input length whichever path runs.
  • 1 per item a collection operator copies, examines or compares, charged before the work: merge per item of each array argument, in per item of an array haystack, missing / missing_some per path of a path list from data, keys / values / entries per key, a stepped slice per item produced, distinct / group_by per comparison, sort n·⌈log₂ n⌉, and one-argument arithmetic per array item. Iterating an object costs 1 per key.
  • The structural walk of an equality between containers: 1 per array element, |a| x |b| per object level, for each level the comparison reaches.
  • 1 per whole 64 bytes of string a string operator reads (cat, substr, upper, lower, trim, length, split, in on a string, starts_with / ends_with, string slice), so strings under 64 bytes are free.
  • Whatever an operator charges for itself. The tensor family prices each operator at max(elements read, elements produced), before it allocates. A crate::CustomOperator that walks a large input should do the same via EvalContext::charge.
  • A CSE-memoised subtree is charged once, on the evaluation that fills the slot.

The count is deterministic for a pinned crate version and a given (rule, data) pair, whichever evaluation path runs: an iterator fast path charges what the general path would for the same data, so tracing and MissingVar::Error, which turn the fast paths off, leave it unchanged. It is not stable across versions: a new fold changes what gets dispatched. Budget for the work you want to allow, not for an exact number you measured.

§Example
use bumpalo::Bump;
use datalogic_rs::{Engine, ErrorCode};

let engine = Engine::new();
let compiled = engine.compile(r#"{"map": [{"var": "xs"}, {"*": [{"var": ""}, 2]}]}"#).unwrap();
let arena = Bump::new();

let metered = engine
    .evaluate_metered(&compiled, r#"{"xs": [1, 2, 3]}"#, &arena, u64::MAX)
    .unwrap();
assert_eq!(metered.value.to_json_string(), "[2,4,6]");
assert!(metered.ops >= 3, "at least one operation per item");

// Too tight a budget refuses the evaluation instead of running it.
let err = engine
    .evaluate_metered(&compiled, r#"{"xs": [1, 2, 3]}"#, &arena, 2)
    .unwrap_err();
assert_eq!(err.code(), ErrorCode::BudgetExceeded);
§Errors

ErrorKind::BudgetExceeded when the rule charges past budget, plus every error Self::evaluate can return. To observe the operations spent even when evaluation fails, call Self::evaluate_metered_report.

Source

pub fn evaluate_metered_report<'a, D: EvalInput<'a>>( &self, compiled: &'a Logic, data: D, arena: &'a Bump, budget: u64, ) -> Metered<Result<&'a DataValue<'a>>>

Available on crate feature budget only.

Failure-inclusive counterpart to Self::evaluate_metered: evaluates under budget and returns a Metered report whose ops is populated whether evaluation succeeds (value: Ok(...)) or fails (value: Err(...)).

Hosts that reserve capacity from a shared parent ledger before an expression runs can reconcile the reservation against report.ops on both successful and failed evaluations, instead of either dropping failed work or conservatively charging the entire reservation.

§Charge semantics on failure
  • Ordinary runtime failures (Thrown, VariableNotFound, TypeError, ArithmeticError, Custom, …): report.ops is the exact number of operations charged before the failing node or operator aborted. Because every node and operator charges before doing its work, the failing node’s own dispatch charge (and any pre-allocation charge it made before raising) is included. The crate::Error in report.value retains its full Error::code, Error::operator, and Error::node_ids breadcrumb.
  • Budget exhaustion (ErrorKind::BudgetExceeded { budget, spent }): every charge is added to the running counter before comparing against budget, so report.ops equals spent — the attempted total that crossed the ceiling. Do not add report.ops and spent together (they are the same counter); a host debiting a reserved slice of size budget can debit report.ops.min(budget) for bounded work or report.ops for attempted work.
  • Pre-dispatch failures (input adaptation / JSON parse errors from data, or exceeding max_recursion_depth at the boundary): no node is dispatched, so report.ops == 0.
§Example
use bumpalo::Bump;
use datalogic_rs::{Engine, ErrorCode, Metered};

let engine = Engine::new();
let compiled = engine.compile(r#"{"/": [1, {"var": "zero"}]}"#).unwrap();
let arena = Bump::new();

let Metered { value, ops } = engine
    .evaluate_metered_report(&compiled, r#"{"zero": 0}"#, &arena, 100);
let err = value.unwrap_err();
assert_eq!(err.code(), ErrorCode::Thrown);
assert_eq!(err.operator(), Some("/"));
assert_eq!(ops, 2, "the `/` and the `var` were dispatched before division failed");
Source

pub fn truthy(&self, value: &DataValue<'_>) -> bool

Apply the engine’s configured truthiness rules (crate::TruthyEvaluator) to an evaluated value.

This is the same coercion if / and / or / ! apply to their operands, exposed so callers (and bindings) can collapse any rule result to a boolean without re-implementing the engine’s configured semantics.

§Example
use bumpalo::Bump;
use datalogic_rs::Engine;

let engine = Engine::new();
let compiled = engine.compile(r#"{"var": "items"}"#).unwrap();
let arena = Bump::new();
let result = engine.evaluate(&compiled, r#"{"items": [1]}"#, &arena).unwrap();
assert!(engine.truthy(result));
Source

pub fn truthy_of<V: TruthyInput>(&self, value: V) -> bool

Self::truthy for a value in any representation the host holds: &OwnedDataValue, &serde_json::Value, &ParsedData or &DataValue (see crate::TruthyInput).

Use it instead of re-implementing truthiness on a result: the answer follows the engine’s crate::TruthyEvaluator, and under the default rules an empty object is falsy, like an empty array, which hand-written checks often miss.

§Example
use datalogic_rs::Engine;
use serde_json::json;

let engine = Engine::new();
let result: serde_json::Value = engine
    .eval_into(r#"{"var": "claims"}"#, &json!({"claims": {}}))
    .unwrap();
assert!(!engine.truthy_of(&result));
assert!(engine.truthy_of(&json!({"sub": "ana"})));
Source

pub fn eval<R, D>(&self, rule: R, data: D) -> Result<OwnedDataValue>
where R: IntoLogic, D: OwnedInput,

One-shot evaluation returning datavalue::OwnedDataValue.

Compiles rule, parses data, evaluates against a fresh per-call arena, and deep-clones the result out. For the same rule run repeatedly, escalate to Self::compile + a Session.

§Example
use datalogic_rs::Engine;

let engine = Engine::new();
let result = engine.eval(
    r#"{"+": [{"var": "x"}, 1]}"#,
    r#"{"x": 41}"#,
).unwrap();
assert_eq!(result.as_i64(), Some(42));
Source

pub fn eval_str<R, D>(&self, rule: R, data: D) -> Result<String>
where R: IntoLogic, D: OwnedInput,

One-shot evaluation returning a JSON String.

§Example
use datalogic_rs::Engine;

let engine = Engine::new();
let result = engine.eval_str(
    r#"{"==": [{"var": "x"}, 5]}"#,
    r#"{"x": 5}"#,
).unwrap();
assert_eq!(result, "true");
Source

pub fn eval_into<T, R, D>(&self, rule: R, data: D) -> Result<T>

Available on crate feature serde_json only.

One-shot evaluation deserialised into a typed T: DeserializeOwned.

Use T = serde_json::Value for a JSON Value result; use a typed struct for direct mapping. Internally routes through serde_json (round-trips the result through a JSON value).

§Example
use datalogic_rs::Engine;
use serde_json::Value;

let engine = Engine::new();
let result: Value = engine.eval_into(
    r#"{"+": [{"var": "x"}, 1]}"#,
    r#"{"x": 41}"#,
).unwrap();
assert_eq!(result, Value::from(42));
Source

pub fn eval_as<O, R, D>(&self, rule: R, data: D) -> Result<O>

One-shot evaluation converting the result straight into O, any crate::FromDataValue output: OwnedDataValue, a JSON String, or a serde_json::Value (with serde_json).

For a serde_json::Value result this is one conversion, where eval_into::<serde_json::Value> (with serde_json) builds the value and then deserializes it into a second one.

use datalogic_rs::Engine;

let engine = Engine::new();
let user: serde_json::Value = engine
    .eval_as(r#"{"var": "user"}"#, r#"{"user": {"id": 7}}"#)
    .unwrap();
assert_eq!(user["id"], 7);

Trait Implementations§

Source§

impl Debug for Engine

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Engine

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.