Skip to main content

Service

Struct Service 

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

Genetic algorithm optimization service that manages the entire optimization lifecycle. Handles request creation, population generation, genotype evaluation, and breeding.

Implementations§

Source§

impl Service

Source

pub async fn new_optimization_request( &self, type_name: &str, type_hash: i32, goal: FitnessGoal, schedule: Schedule, selector: Selector, mutagen: Mutagen, crossover: Crossover, distribution: Distribution, data: Option<impl Serialize + Send + Sync>, ) -> Result<Uuid, Error>

Creates a new genetic algorithm optimization request.

This is the main entry point for starting genetic algorithm optimization. It configures and initiates an evolutionary process that will attempt to find optimal solutions for your problem type.

§Parameters
  • type_name - Human-readable name of the type being optimized (from Encodeable::NAME)
  • type_hash - Unique hash identifying the type structure (from Encodeable::HASH)
  • goal - Optimization objective and stopping criteria
  • schedule - Controls generation timing and population lifecycle
  • selector - Parent selection strategy for breeding operations
  • mutagen - Mutation behavior including temperature and rate schedules
  • crossover - Genetic recombination method for combining parents
  • distribution - Initial population generation strategy
§Optimization Goal

The goal parameter defines when optimization should stop:

  • FitnessGoal::maximize(0.95) - Stop when fitness reaches 95% or higher
  • FitnessGoal::minimize(0.1) - Stop when fitness drops to 10% or lower
§Population Management

The schedule controls generation timing and resource allocation:

  • Schedule::generational(100, 50) - 100 generations, 50 individuals each
  • Schedule::rolling(5000, 100, 10) - 5000 total evaluations, 100 max population, breed 10 at a time
§Parent Selection

The selector determines how parents are chosen for breeding:

  • Selector::tournament(3, 100) - Tournament selection (size 3) from 100 candidates
  • Selector::roulette(100) - Fitness-proportionate selection from 100 candidates
§Mutation Strategy

The mutagen combines temperature (step size) and mutation rate (frequency):

  • Mutagen::constant(0.5, 0.3) - Fixed 50% temperature, 30% mutation rate
  • Adaptive strategies use Temperature::linear() and MutationRate::exponential()
§Genetic Recombination

The crossover method combines genetic material from parents:

  • Crossover::uniform(0.5) - Each gene has 50% chance from first parent
  • Crossover::single_point() - Cut genome at random point, swap tails
§Initial Population

The distribution strategy affects initial diversity and convergence:

  • Distribution::latin_hypercube(50) - Structured sampling for better coverage
  • Distribution::random(50) - Pure random sampling
§Common Configurations
§Quick Convergence (Time-Constrained)
use fx_durable_ga::models::*;

service.new_optimization_request(
    MyType::NAME,
    MyType::HASH,
    FitnessGoal::maximize(0.90)?,                    // Modest target
    Schedule::generational(20, 30),                 // Small, fast generations
    Selector::tournament(5, 50)?,                    // Strong selection pressure
    Mutagen::new(
        Temperature::exponential(0.8, 0.1, 1.2, 3)?, // Rapid cooling
        MutationRate::exponential(0.6, 0.05, 1.1, 2)?
    ),
    Crossover::uniform(0.6)?,                       // High recombination
    Distribution::latin_hypercube(30),
    None::<()>,
).await?;
§Balanced Search (General Purpose)
use fx_durable_ga::models::*;

service.new_optimization_request(
    MyType::NAME,
    MyType::HASH,
    FitnessGoal::maximize(0.95)?,                    // High-quality target
    Schedule::generational(50, 50),                 // Moderate generations
    Selector::tournament(3, 100)?,                   // Balanced selection
    Mutagen::new(
        Temperature::linear(0.7, 0.2, 1.0)?,         // Gradual cooling
        MutationRate::linear(0.4, 0.1, 1.0)?
    ),
    Crossover::uniform(0.5)?,                       // Balanced recombination
    Distribution::latin_hypercube(50),
    None::<()>,
).await?;
§Thorough Exploration (Complex Problems)
use fx_durable_ga::models::*;

service.new_optimization_request(
    MyType::NAME,
    MyType::HASH,
    FitnessGoal::maximize(0.99)?,                    // High precision target
    Schedule::rolling(10000, 200, 20),              // Large budget
    Selector::tournament(2, 150)?,                   // Low selection pressure
    Mutagen::constant(0.6, 0.4)?,                   // Sustained exploration
    Crossover::single_point(),                      // Conservative recombination
    Distribution::latin_hypercube(100),             // High initial diversity
    None::<()>,
).await?;
§Parameter Interactions

Key relationships to consider:

  • High selection pressure + Low mutation: Fast convergence, may get stuck
  • Low selection pressure + High mutation: Slow convergence, good exploration
  • Large populations + Tournament selection: Better genetic diversity
  • Small populations + Roulette selection: Risk of premature convergence
  • Exponential decay + Generational schedule: Classic simulated annealing
  • Linear decay + Rolling schedule: Steady refinement over time
§Returns

Returns Ok(()) if the optimization request was successfully created and scheduled. The actual optimization runs asynchronously via the event/job system.

§Errors
  • Returns error if the specified type hasn’t been registered with an evaluator
  • Returns error if database operations fail
  • Parameter validation errors are caught at construction time (e.g., FitnessGoal::maximize(1.5) fails)
§Example Usage
use fx_durable_ga::models::*;

// Define your problem type
#[derive(Debug)]
struct Point { x: f64, y: f64 }

impl Encodeable for Point {
    const NAME: &'static str = "Point";
    type Phenotype = Point;
    fn morphology() -> Vec<GeneBounds> {
        vec![
            GeneBounds::decimal(0.0, 10.0, 1000, 3).unwrap(),
            GeneBounds::decimal(0.0, 10.0, 1000, 3).unwrap(),
        ]
    }
    fn encode(&self) -> Vec<i64> {
        let bounds = Self::morphology();
        vec![
            bounds[0].from_sample(self.x / 10.0),
            bounds[1].from_sample(self.y / 10.0),
        ]
    }
    fn decode(genes: &[i64]) -> Self::Phenotype {
        let bounds = Self::morphology();
        Point {
            x: bounds[0].decode_f64(genes[0]),
            y: bounds[1].decode_f64(genes[1]),
        }
    }
}

// Start optimization
service.new_optimization_request(
    Point::NAME,
    Point::HASH,
    FitnessGoal::maximize(0.95)?,
    Schedule::generational(50, 50),
    Selector::tournament(3, 100)?,
    Mutagen::constant(0.5, 0.3)?,
    Crossover::uniform(0.5)?,
    Distribution::latin_hypercube(50),
    None::<()>,
).await?;
Examples found in repository?
examples/regression_model.rs (lines 241-251)
195async fn main() -> Result<()> {
196    dotenv::from_filename(".env.local").ok();
197    tracing_subscriber::fmt()
198        .pretty()
199        .with_thread_ids(true)
200        .with_max_level(Level::INFO)
201        .init();
202
203    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
204    let pool = PgPoolOptions::new()
205        .max_connections(10)
206        .connect(&database_url)
207        .await?;
208
209    // Run all default migrations
210    fx_durable_ga::migrations::run_default_migrations(&pool).await?;
211
212    let service = Arc::new(
213        bootstrap(pool.clone())
214            .await?
215            .register::<NeuralArchitecture, _>(ArchitectureEvaluator)
216            .await?
217            .build(),
218    );
219
220    let mut registry = fx_event_bus::EventHandlerRegistry::new();
221    register_event_handlers(
222        Arc::new(Queries::new(FX_MQ_JOBS_SCHEMA_NAME)),
223        service.clone(),
224        &mut registry,
225    );
226    let mut listener = fx_event_bus::Listener::new(pool.clone(), registry);
227    tokio::spawn(async move { listener.listen(None).await });
228
229    let host_id = Uuid::parse_str("00000000-0000-0000-0000-123456789abc")?;
230    let mut jobs_listener = fx_mq_jobs::Listener::new(
231        pool.clone(),
232        register_job_handlers(&service, fx_mq_jobs::RegistryBuilder::new()),
233        WORKERS,
234        host_id,
235        Duration::from_secs(600),
236    )
237    .await?;
238    tokio::spawn(async move { jobs_listener.listen().await });
239
240    service
241        .new_optimization_request(
242            NeuralArchitecture::NAME,
243            NeuralArchitecture::HASH,
244            FitnessGoal::minimize(FITNESS_TARGET)?,
245            Schedule::generational(10, 10),
246            Selector::tournament(5, 15)?,
247            Mutagen::new(Temperature::constant(0.8)?, MutationRate::constant(0.4)?),
248            Crossover::uniform(0.5)?,
249            Distribution::latin_hypercube(15),
250            None::<()>,
251        )
252        .await?;
253
254    tokio::time::sleep(Duration::from_secs(3600)).await;
255    Ok(())
256}
More examples
Hide additional examples
examples/point_search.rs (lines 195-205)
130async fn main() -> Result<()> {
131    dotenv::from_filename(".env.local").ok();
132
133    // Initialize logging to see optimization progress
134    tracing_subscriber::fmt()
135        .with_max_level(tracing::Level::INFO)
136        .init();
137
138    // Database setup - genetic algorithms need persistent storage for populations
139    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
140    let pool = PgPoolOptions::new()
141        .max_connections(50)
142        .connect(&database_url)
143        .await?;
144
145    fx_event_bus::run_migrations(&pool).await?;
146    fx_mq_jobs::run_migrations(&pool, fx_mq_jobs::FX_MQ_JOBS_SCHEMA_NAME).await?;
147
148    // Bootstrap the optimization service and register our problem type
149    let target_point = Point {
150        x: 1.0,
151        y: 1.5,
152        z: 2.5,
153    }; // Target point to find
154    let evaluator = PointDistanceEvaluator { target_point };
155    let service = Arc::new(
156        bootstrap(pool.clone())
157            .await?
158            .register::<Point, _>(evaluator)
159            .await?
160            .build(),
161    );
162
163    // setup event handling and spawn an event handling agent
164    let mut registry = fx_event_bus::EventHandlerRegistry::new();
165    register_event_handlers(
166        Arc::new(Queries::new(FX_MQ_JOBS_SCHEMA_NAME)),
167        service.clone(),
168        &mut registry,
169    );
170    let mut listener = fx_event_bus::Listener::new(pool.clone(), registry);
171    let _events_handle = tokio::spawn(async move {
172        listener.listen(None).await?;
173        Ok::<(), sqlx::Error>(())
174    });
175
176    // setup job handling and initiate workers
177    let host_id = Uuid::parse_str("ba3a4752-c4ce-4129-aa1d-55a0b2107e68").expect("valid uuid");
178    let hold_for = Duration::from_secs(TIMEOUT_SECONDS);
179    let mut jobs_listener = fx_mq_jobs::Listener::new(
180        pool.clone(),
181        register_job_handlers(&service, fx_mq_jobs::RegistryBuilder::new()),
182        8,
183        host_id,
184        hold_for,
185    )
186    .await?;
187    let _jobs_handle = tokio::spawn(async move {
188        jobs_listener.listen().await?;
189        Ok::<(), anyhow::Error>(())
190    });
191
192    // Create multiple optimization requests with different genetic algorithm parameters
193    for _ in 0..1 {
194        service
195            .new_optimization_request(
196                Point::NAME,
197                Point::HASH,
198                FitnessGoal::minimize(0.01)?, // Stop when distance ≤ 0.01
199                Schedule::generational(200, 30),
200                Selector::tournament(7, 100)?,
201                Mutagen::new(Temperature::constant(0.7)?, MutationRate::constant(0.3)?),
202                Crossover::uniform(0.5)?,
203                Distribution::latin_hypercube(1000),
204                None::<()>,
205            )
206            .await?;
207    }
208
209    let timeout_duration = Duration::from_secs(TIMEOUT_SECONDS);
210    let start_time = std::time::Instant::now();
211
212    loop {
213        tokio::time::sleep(Duration::from_secs(1)).await;
214
215        // Check if we've exceeded the timeout
216        if start_time.elapsed() >= timeout_duration {
217            println!(
218                "Timeout reached after {} seconds. Stopping optimization.",
219                timeout_duration.as_secs()
220            );
221            break;
222        }
223    }
224
225    Ok(())
226}
examples/feature_engineering.rs (lines 423-433)
377async fn main() -> Result<()> {
378    dotenv::from_filename(".env.local").ok();
379    tracing_subscriber::fmt()
380        .pretty()
381        .with_thread_ids(true)
382        .with_max_level(Level::INFO)
383        .init();
384
385    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
386    let pool = PgPoolOptions::new()
387        .max_connections(10)
388        .connect(&database_url)
389        .await?;
390
391    // Run all default migrations
392    fx_durable_ga::migrations::run_default_migrations(&pool).await?;
393
394    let service = Arc::new(
395        bootstrap(pool.clone())
396            .await?
397            .register::<FeatureConfig, _>(FeatureEvaluator)
398            .await?
399            .build(),
400    );
401
402    let mut registry = fx_event_bus::EventHandlerRegistry::new();
403    register_event_handlers(
404        Arc::new(Queries::new(FX_MQ_JOBS_SCHEMA_NAME)),
405        service.clone(),
406        &mut registry,
407    );
408    let mut listener = fx_event_bus::Listener::new(pool.clone(), registry);
409    tokio::spawn(async move { listener.listen(None).await });
410
411    let host_id = Uuid::parse_str("00000000-0000-0000-0000-123456789abc")?;
412    let mut jobs_listener = fx_mq_jobs::Listener::new(
413        pool.clone(),
414        register_job_handlers(&service, fx_mq_jobs::RegistryBuilder::new()),
415        WORKERS,
416        host_id,
417        Duration::from_secs(600),
418    )
419    .await?;
420    tokio::spawn(async move { jobs_listener.listen().await });
421
422    let request_id = service
423        .new_optimization_request(
424            FeatureConfig::NAME,
425            FeatureConfig::HASH,
426            FitnessGoal::minimize(FITNESS_TARGET)?,
427            Schedule::generational(40, 10),
428            Selector::tournament(5, 45)?,
429            Mutagen::new(Temperature::constant(0.7)?, MutationRate::constant(0.35)?),
430            Crossover::uniform(0.5)?,
431            Distribution::latin_hypercube(40),
432            None::<()>,
433        )
434        .await?;
435
436    // Poll for completion every 15 seconds (timeout after 1 hour)
437    let timeout = Duration::from_secs(7200);
438    let poll_interval = Duration::from_secs(15);
439    let start = std::time::Instant::now();
440
441    loop {
442        if service.is_request_concluded(request_id).await? {
443            println!("\nOptimization completed!");
444            break;
445        }
446
447        if start.elapsed() > timeout {
448            println!("\nOptimization timed out after 1 hour.");
449            break;
450        }
451
452        tokio::time::sleep(poll_interval).await;
453    }
454
455    // Get and print the best configuration
456    if let Some((genotype, fitness)) = service.get_best_genotype(request_id).await? {
457        let config = FeatureConfig::decode(&genotype.genome());
458        println!("\n=== Best Configuration ===");
459        println!("Fitness (MSE): {:.6}", fitness);
460        println!("RMSE: {:.6}°C", fitness.sqrt());
461        println!("\nHyperparameters:");
462        println!("  Hidden Size: {}", config.hidden_size);
463        println!("  Learning Rate: {}", config.learning_rate);
464        println!("  Sequence Length: {}", config.sequence_length);
465        println!("\nFeatures:");
466        for (i, feature) in config.features.iter().enumerate() {
467            let pipeline = feature
468                .transforms
469                .iter()
470                .map(|t| t.to_string())
471                .collect::<Vec<_>>()
472                .join(" → ");
473            if pipeline.is_empty() {
474                println!("  feat_{}: {}", i, feature.source);
475            } else {
476                println!("  feat_{}: {} → {}", i, feature.source, pipeline);
477            }
478        }
479    } else {
480        println!("No genotypes were evaluated.");
481    }
482
483    Ok(())
484}
Source

pub async fn interrupt_request(&self, request_id: Uuid) -> Result<(), Error>

Interrupts a running optimization request. Publishes an interruption event that concludes the request with the “Interrupted” reason.

Source

pub async fn get_best_genotype( &self, request_id: Uuid, ) -> Result<Option<(Genotype, f64)>, Error>

Gets the best genotype for a request based on fitness. Returns the genotype with the best (min or max) fitness depending on the goal.

Examples found in repository?
examples/feature_engineering.rs (line 456)
377async fn main() -> Result<()> {
378    dotenv::from_filename(".env.local").ok();
379    tracing_subscriber::fmt()
380        .pretty()
381        .with_thread_ids(true)
382        .with_max_level(Level::INFO)
383        .init();
384
385    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
386    let pool = PgPoolOptions::new()
387        .max_connections(10)
388        .connect(&database_url)
389        .await?;
390
391    // Run all default migrations
392    fx_durable_ga::migrations::run_default_migrations(&pool).await?;
393
394    let service = Arc::new(
395        bootstrap(pool.clone())
396            .await?
397            .register::<FeatureConfig, _>(FeatureEvaluator)
398            .await?
399            .build(),
400    );
401
402    let mut registry = fx_event_bus::EventHandlerRegistry::new();
403    register_event_handlers(
404        Arc::new(Queries::new(FX_MQ_JOBS_SCHEMA_NAME)),
405        service.clone(),
406        &mut registry,
407    );
408    let mut listener = fx_event_bus::Listener::new(pool.clone(), registry);
409    tokio::spawn(async move { listener.listen(None).await });
410
411    let host_id = Uuid::parse_str("00000000-0000-0000-0000-123456789abc")?;
412    let mut jobs_listener = fx_mq_jobs::Listener::new(
413        pool.clone(),
414        register_job_handlers(&service, fx_mq_jobs::RegistryBuilder::new()),
415        WORKERS,
416        host_id,
417        Duration::from_secs(600),
418    )
419    .await?;
420    tokio::spawn(async move { jobs_listener.listen().await });
421
422    let request_id = service
423        .new_optimization_request(
424            FeatureConfig::NAME,
425            FeatureConfig::HASH,
426            FitnessGoal::minimize(FITNESS_TARGET)?,
427            Schedule::generational(40, 10),
428            Selector::tournament(5, 45)?,
429            Mutagen::new(Temperature::constant(0.7)?, MutationRate::constant(0.35)?),
430            Crossover::uniform(0.5)?,
431            Distribution::latin_hypercube(40),
432            None::<()>,
433        )
434        .await?;
435
436    // Poll for completion every 15 seconds (timeout after 1 hour)
437    let timeout = Duration::from_secs(7200);
438    let poll_interval = Duration::from_secs(15);
439    let start = std::time::Instant::now();
440
441    loop {
442        if service.is_request_concluded(request_id).await? {
443            println!("\nOptimization completed!");
444            break;
445        }
446
447        if start.elapsed() > timeout {
448            println!("\nOptimization timed out after 1 hour.");
449            break;
450        }
451
452        tokio::time::sleep(poll_interval).await;
453    }
454
455    // Get and print the best configuration
456    if let Some((genotype, fitness)) = service.get_best_genotype(request_id).await? {
457        let config = FeatureConfig::decode(&genotype.genome());
458        println!("\n=== Best Configuration ===");
459        println!("Fitness (MSE): {:.6}", fitness);
460        println!("RMSE: {:.6}°C", fitness.sqrt());
461        println!("\nHyperparameters:");
462        println!("  Hidden Size: {}", config.hidden_size);
463        println!("  Learning Rate: {}", config.learning_rate);
464        println!("  Sequence Length: {}", config.sequence_length);
465        println!("\nFeatures:");
466        for (i, feature) in config.features.iter().enumerate() {
467            let pipeline = feature
468                .transforms
469                .iter()
470                .map(|t| t.to_string())
471                .collect::<Vec<_>>()
472                .join(" → ");
473            if pipeline.is_empty() {
474                println!("  feat_{}: {}", i, feature.source);
475            } else {
476                println!("  feat_{}: {} → {}", i, feature.source, pipeline);
477            }
478        }
479    } else {
480        println!("No genotypes were evaluated.");
481    }
482
483    Ok(())
484}
Source

pub async fn is_request_concluded( &self, request_id: Uuid, ) -> Result<bool, Error>

Checks if an optimization request has concluded. Returns true if the request has been completed or terminated.

Examples found in repository?
examples/feature_engineering.rs (line 442)
377async fn main() -> Result<()> {
378    dotenv::from_filename(".env.local").ok();
379    tracing_subscriber::fmt()
380        .pretty()
381        .with_thread_ids(true)
382        .with_max_level(Level::INFO)
383        .init();
384
385    let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
386    let pool = PgPoolOptions::new()
387        .max_connections(10)
388        .connect(&database_url)
389        .await?;
390
391    // Run all default migrations
392    fx_durable_ga::migrations::run_default_migrations(&pool).await?;
393
394    let service = Arc::new(
395        bootstrap(pool.clone())
396            .await?
397            .register::<FeatureConfig, _>(FeatureEvaluator)
398            .await?
399            .build(),
400    );
401
402    let mut registry = fx_event_bus::EventHandlerRegistry::new();
403    register_event_handlers(
404        Arc::new(Queries::new(FX_MQ_JOBS_SCHEMA_NAME)),
405        service.clone(),
406        &mut registry,
407    );
408    let mut listener = fx_event_bus::Listener::new(pool.clone(), registry);
409    tokio::spawn(async move { listener.listen(None).await });
410
411    let host_id = Uuid::parse_str("00000000-0000-0000-0000-123456789abc")?;
412    let mut jobs_listener = fx_mq_jobs::Listener::new(
413        pool.clone(),
414        register_job_handlers(&service, fx_mq_jobs::RegistryBuilder::new()),
415        WORKERS,
416        host_id,
417        Duration::from_secs(600),
418    )
419    .await?;
420    tokio::spawn(async move { jobs_listener.listen().await });
421
422    let request_id = service
423        .new_optimization_request(
424            FeatureConfig::NAME,
425            FeatureConfig::HASH,
426            FitnessGoal::minimize(FITNESS_TARGET)?,
427            Schedule::generational(40, 10),
428            Selector::tournament(5, 45)?,
429            Mutagen::new(Temperature::constant(0.7)?, MutationRate::constant(0.35)?),
430            Crossover::uniform(0.5)?,
431            Distribution::latin_hypercube(40),
432            None::<()>,
433        )
434        .await?;
435
436    // Poll for completion every 15 seconds (timeout after 1 hour)
437    let timeout = Duration::from_secs(7200);
438    let poll_interval = Duration::from_secs(15);
439    let start = std::time::Instant::now();
440
441    loop {
442        if service.is_request_concluded(request_id).await? {
443            println!("\nOptimization completed!");
444            break;
445        }
446
447        if start.elapsed() > timeout {
448            println!("\nOptimization timed out after 1 hour.");
449            break;
450        }
451
452        tokio::time::sleep(poll_interval).await;
453    }
454
455    // Get and print the best configuration
456    if let Some((genotype, fitness)) = service.get_best_genotype(request_id).await? {
457        let config = FeatureConfig::decode(&genotype.genome());
458        println!("\n=== Best Configuration ===");
459        println!("Fitness (MSE): {:.6}", fitness);
460        println!("RMSE: {:.6}°C", fitness.sqrt());
461        println!("\nHyperparameters:");
462        println!("  Hidden Size: {}", config.hidden_size);
463        println!("  Learning Rate: {}", config.learning_rate);
464        println!("  Sequence Length: {}", config.sequence_length);
465        println!("\nFeatures:");
466        for (i, feature) in config.features.iter().enumerate() {
467            let pipeline = feature
468                .transforms
469                .iter()
470                .map(|t| t.to_string())
471                .collect::<Vec<_>>()
472                .join(" → ");
473            if pipeline.is_empty() {
474                println!("  feat_{}: {}", i, feature.source);
475            } else {
476                println!("  feat_{}: {} → {}", i, feature.source, pipeline);
477            }
478        }
479    } else {
480        println!("No genotypes were evaluated.");
481    }
482
483    Ok(())
484}
Source

pub async fn search_genotypes( &self, filter: &Filter, limit: i64, ) -> Result<Vec<(Genotype, Option<f64>)>, Error>

Get a morphology by its type name

Source

pub async fn get_phenotype<T: Encodeable>( &self, genotype_id: &Uuid, ) -> Result<T::Phenotype, Error>

Get a phenotype by its type name

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<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more