Skip to main content

AsyncClient

Struct AsyncClient 

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

Low-level Tokio IRTT client for one connected UDP target.

AsyncClient does not construct, own, or store a Tokio runtime. Its async methods are polled by the caller and require a current Tokio runtime with I/O and time enabled.

§Example

Use this low-level adapter when the application already owns Tokio and wants to drive the session lifecycle itself. This example type-checks without contacting a server.

use irtt_client::{AsyncClient, ClientConfig};

let mut client = AsyncClient::connect(ClientConfig::default()).await?;
let outcome = client.open().await?;
println!("opened: {outcome:?}");
let sent = client.send_probe().await?;
println!("sent: {sent:?}");
let received = client.recv().await?;
println!("received: {received:?}");
let timed_out = client.poll_timeouts()?;
println!("timeouts: {timed_out:?}");
let closed = client.close().await?;
println!("closed: {closed:?}");

Implementations§

Source§

impl AsyncClient

Source

pub async fn connect(config: ClientConfig) -> Result<Self, ClientError>

Resolve the configured server and construct one connected Tokio UDP socket.

Polling this future without a current Tokio runtime returns ClientError::NoTokioRuntime. A runtime without enabled I/O or time drivers is outside this type’s runtime contract.

Examples found in repository?
examples/tokio_client.rs (line 53)
42async fn run() {
43    let config = ClientConfig {
44        server_addr: "127.0.0.1:2112".to_owned(),
45        duration: Some(Duration::from_secs(2)),
46        interval: Duration::from_millis(200),
47        // A single short attempt keeps this example fast when no server is
48        // reachable; production callers should generally keep the default.
49        open_timeouts: vec![Duration::from_millis(300)],
50        ..Default::default()
51    };
52
53    let mut client = match AsyncClient::connect(config).await {
54        Ok(client) => client,
55        Err(err) => {
56            eprintln!("failed to prepare client socket: {err}");
57            return;
58        }
59    };
60
61    match client.open().await {
62        Ok(outcome) => println!("session opened: {outcome:?}"),
63        Err(err) => {
64            eprintln!("open failed (is a server running at 127.0.0.1:2112?): {err}");
65            return;
66        }
67    }
68
69    while !client.is_run_complete() {
70        // Bound the receive wait by the next send/timeout deadline, rather
71        // than awaiting recv() unconditionally: a lost or rate-limited reply
72        // must not stall pacing or timeout classification indefinitely.
73        let wake_at = client
74            .next_send_deadline()
75            .into_iter()
76            .chain(std::iter::once(Instant::now() + TIMEOUT_POLL_INTERVAL))
77            .min()
78            .expect("the fixed poll-interval deadline is always present");
79
80        let recv_result = tokio::select! {
81            events = client.recv() => Some(events),
82            () = tokio::time::sleep_until(tokio::time::Instant::from_std(wake_at)) => None,
83        };
84        if let Some(result) = recv_result {
85            match result {
86                Ok(events) => events.iter().for_each(print_event),
87                Err(err) => {
88                    eprintln!("receive failed: {err}");
89                    break;
90                }
91            }
92        }
93
94        if client
95            .next_send_deadline()
96            .is_some_and(|send_at| Instant::now() >= send_at)
97        {
98            // A failed send retains its prepared probe without advancing the
99            // schedule, so a persistent error (e.g. the interface going
100            // down) would otherwise make this loop retry forever instead of
101            // reporting it.
102            match client.send_probe().await {
103                Ok(events) => events.iter().for_each(print_event),
104                Err(err) => {
105                    eprintln!("send failed: {err}");
106                    break;
107                }
108            }
109        }
110        match client.poll_timeouts() {
111            Ok(events) => events.iter().for_each(print_event),
112            Err(err) => {
113                eprintln!("timeout polling failed: {err}");
114                break;
115            }
116        }
117    }
118
119    match client.close().await {
120        Ok(events) => events.iter().for_each(print_event),
121        Err(err) => eprintln!("close failed: {err}"),
122    }
123}
Source

pub async fn open(&mut self) -> Result<OpenOutcome, ClientError>

Perform the IRTT open exchange.

Each configured attempt uses one absolute deadline for one successful request submission and all replies inspected during that attempt. Malformed, unrelated, wrong-direction, and unauthenticated datagrams are ignored without resending the request.

Dropping this future before trusted acceptance leaves the local machine connected with no committed schedule or negotiated adapter state. If it is dropped during best-effort post-token cleanup, cleanup may remain incomplete because this low-level client never detaches cleanup work.

Examples found in repository?
examples/tokio_client.rs (line 61)
42async fn run() {
43    let config = ClientConfig {
44        server_addr: "127.0.0.1:2112".to_owned(),
45        duration: Some(Duration::from_secs(2)),
46        interval: Duration::from_millis(200),
47        // A single short attempt keeps this example fast when no server is
48        // reachable; production callers should generally keep the default.
49        open_timeouts: vec![Duration::from_millis(300)],
50        ..Default::default()
51    };
52
53    let mut client = match AsyncClient::connect(config).await {
54        Ok(client) => client,
55        Err(err) => {
56            eprintln!("failed to prepare client socket: {err}");
57            return;
58        }
59    };
60
61    match client.open().await {
62        Ok(outcome) => println!("session opened: {outcome:?}"),
63        Err(err) => {
64            eprintln!("open failed (is a server running at 127.0.0.1:2112?): {err}");
65            return;
66        }
67    }
68
69    while !client.is_run_complete() {
70        // Bound the receive wait by the next send/timeout deadline, rather
71        // than awaiting recv() unconditionally: a lost or rate-limited reply
72        // must not stall pacing or timeout classification indefinitely.
73        let wake_at = client
74            .next_send_deadline()
75            .into_iter()
76            .chain(std::iter::once(Instant::now() + TIMEOUT_POLL_INTERVAL))
77            .min()
78            .expect("the fixed poll-interval deadline is always present");
79
80        let recv_result = tokio::select! {
81            events = client.recv() => Some(events),
82            () = tokio::time::sleep_until(tokio::time::Instant::from_std(wake_at)) => None,
83        };
84        if let Some(result) = recv_result {
85            match result {
86                Ok(events) => events.iter().for_each(print_event),
87                Err(err) => {
88                    eprintln!("receive failed: {err}");
89                    break;
90                }
91            }
92        }
93
94        if client
95            .next_send_deadline()
96            .is_some_and(|send_at| Instant::now() >= send_at)
97        {
98            // A failed send retains its prepared probe without advancing the
99            // schedule, so a persistent error (e.g. the interface going
100            // down) would otherwise make this loop retry forever instead of
101            // reporting it.
102            match client.send_probe().await {
103                Ok(events) => events.iter().for_each(print_event),
104                Err(err) => {
105                    eprintln!("send failed: {err}");
106                    break;
107                }
108            }
109        }
110        match client.poll_timeouts() {
111            Ok(events) => events.iter().for_each(print_event),
112            Err(err) => {
113                eprintln!("timeout polling failed: {err}");
114                break;
115            }
116        }
117    }
118
119    match client.close().await {
120        Ok(events) => events.iter().for_each(print_event),
121        Err(err) => eprintln!("close failed: {err}"),
122    }
123}
Source

pub async fn send_probe(&mut self) -> Result<Vec<ClientEvent>, ClientError>

Send one caller-paced probe with transactional protocol and schedule commits.

A prepared packet is retained across readiness false positives, cancellation, and socket errors so a later call retries the same logical probe without advancing state before kernel acceptance.

Examples found in repository?
examples/tokio_client.rs (line 102)
42async fn run() {
43    let config = ClientConfig {
44        server_addr: "127.0.0.1:2112".to_owned(),
45        duration: Some(Duration::from_secs(2)),
46        interval: Duration::from_millis(200),
47        // A single short attempt keeps this example fast when no server is
48        // reachable; production callers should generally keep the default.
49        open_timeouts: vec![Duration::from_millis(300)],
50        ..Default::default()
51    };
52
53    let mut client = match AsyncClient::connect(config).await {
54        Ok(client) => client,
55        Err(err) => {
56            eprintln!("failed to prepare client socket: {err}");
57            return;
58        }
59    };
60
61    match client.open().await {
62        Ok(outcome) => println!("session opened: {outcome:?}"),
63        Err(err) => {
64            eprintln!("open failed (is a server running at 127.0.0.1:2112?): {err}");
65            return;
66        }
67    }
68
69    while !client.is_run_complete() {
70        // Bound the receive wait by the next send/timeout deadline, rather
71        // than awaiting recv() unconditionally: a lost or rate-limited reply
72        // must not stall pacing or timeout classification indefinitely.
73        let wake_at = client
74            .next_send_deadline()
75            .into_iter()
76            .chain(std::iter::once(Instant::now() + TIMEOUT_POLL_INTERVAL))
77            .min()
78            .expect("the fixed poll-interval deadline is always present");
79
80        let recv_result = tokio::select! {
81            events = client.recv() => Some(events),
82            () = tokio::time::sleep_until(tokio::time::Instant::from_std(wake_at)) => None,
83        };
84        if let Some(result) = recv_result {
85            match result {
86                Ok(events) => events.iter().for_each(print_event),
87                Err(err) => {
88                    eprintln!("receive failed: {err}");
89                    break;
90                }
91            }
92        }
93
94        if client
95            .next_send_deadline()
96            .is_some_and(|send_at| Instant::now() >= send_at)
97        {
98            // A failed send retains its prepared probe without advancing the
99            // schedule, so a persistent error (e.g. the interface going
100            // down) would otherwise make this loop retry forever instead of
101            // reporting it.
102            match client.send_probe().await {
103                Ok(events) => events.iter().for_each(print_event),
104                Err(err) => {
105                    eprintln!("send failed: {err}");
106                    break;
107                }
108            }
109        }
110        match client.poll_timeouts() {
111            Ok(events) => events.iter().for_each(print_event),
112            Err(err) => {
113                eprintln!("timeout polling failed: {err}");
114                break;
115            }
116        }
117    }
118
119    match client.close().await {
120        Ok(events) => events.iter().for_each(print_event),
121        Err(err) => eprintln!("close failed: {err}"),
122    }
123}
Source

pub async fn recv(&mut self) -> Result<Vec<ClientEvent>, ClientError>

Await and classify one complete UDP datagram.

State is validated before readiness is awaited. Readiness false positives retry without changing protocol state. Authenticated peer-close events remain authoritative even if best-effort DSCP cleanup fails.

Examples found in repository?
examples/tokio_client.rs (line 81)
42async fn run() {
43    let config = ClientConfig {
44        server_addr: "127.0.0.1:2112".to_owned(),
45        duration: Some(Duration::from_secs(2)),
46        interval: Duration::from_millis(200),
47        // A single short attempt keeps this example fast when no server is
48        // reachable; production callers should generally keep the default.
49        open_timeouts: vec![Duration::from_millis(300)],
50        ..Default::default()
51    };
52
53    let mut client = match AsyncClient::connect(config).await {
54        Ok(client) => client,
55        Err(err) => {
56            eprintln!("failed to prepare client socket: {err}");
57            return;
58        }
59    };
60
61    match client.open().await {
62        Ok(outcome) => println!("session opened: {outcome:?}"),
63        Err(err) => {
64            eprintln!("open failed (is a server running at 127.0.0.1:2112?): {err}");
65            return;
66        }
67    }
68
69    while !client.is_run_complete() {
70        // Bound the receive wait by the next send/timeout deadline, rather
71        // than awaiting recv() unconditionally: a lost or rate-limited reply
72        // must not stall pacing or timeout classification indefinitely.
73        let wake_at = client
74            .next_send_deadline()
75            .into_iter()
76            .chain(std::iter::once(Instant::now() + TIMEOUT_POLL_INTERVAL))
77            .min()
78            .expect("the fixed poll-interval deadline is always present");
79
80        let recv_result = tokio::select! {
81            events = client.recv() => Some(events),
82            () = tokio::time::sleep_until(tokio::time::Instant::from_std(wake_at)) => None,
83        };
84        if let Some(result) = recv_result {
85            match result {
86                Ok(events) => events.iter().for_each(print_event),
87                Err(err) => {
88                    eprintln!("receive failed: {err}");
89                    break;
90                }
91            }
92        }
93
94        if client
95            .next_send_deadline()
96            .is_some_and(|send_at| Instant::now() >= send_at)
97        {
98            // A failed send retains its prepared probe without advancing the
99            // schedule, so a persistent error (e.g. the interface going
100            // down) would otherwise make this loop retry forever instead of
101            // reporting it.
102            match client.send_probe().await {
103                Ok(events) => events.iter().for_each(print_event),
104                Err(err) => {
105                    eprintln!("send failed: {err}");
106                    break;
107                }
108            }
109        }
110        match client.poll_timeouts() {
111            Ok(events) => events.iter().for_each(print_event),
112            Err(err) => {
113                eprintln!("timeout polling failed: {err}");
114                break;
115            }
116        }
117    }
118
119    match client.close().await {
120        Ok(events) => events.iter().for_each(print_event),
121        Err(err) => eprintln!("close failed: {err}"),
122    }
123}
Source

pub fn poll_timeouts(&mut self) -> Result<Vec<ClientEvent>, ClientError>

Poll protocol timeouts using a newly captured monotonic timestamp.

Examples found in repository?
examples/tokio_client.rs (line 110)
42async fn run() {
43    let config = ClientConfig {
44        server_addr: "127.0.0.1:2112".to_owned(),
45        duration: Some(Duration::from_secs(2)),
46        interval: Duration::from_millis(200),
47        // A single short attempt keeps this example fast when no server is
48        // reachable; production callers should generally keep the default.
49        open_timeouts: vec![Duration::from_millis(300)],
50        ..Default::default()
51    };
52
53    let mut client = match AsyncClient::connect(config).await {
54        Ok(client) => client,
55        Err(err) => {
56            eprintln!("failed to prepare client socket: {err}");
57            return;
58        }
59    };
60
61    match client.open().await {
62        Ok(outcome) => println!("session opened: {outcome:?}"),
63        Err(err) => {
64            eprintln!("open failed (is a server running at 127.0.0.1:2112?): {err}");
65            return;
66        }
67    }
68
69    while !client.is_run_complete() {
70        // Bound the receive wait by the next send/timeout deadline, rather
71        // than awaiting recv() unconditionally: a lost or rate-limited reply
72        // must not stall pacing or timeout classification indefinitely.
73        let wake_at = client
74            .next_send_deadline()
75            .into_iter()
76            .chain(std::iter::once(Instant::now() + TIMEOUT_POLL_INTERVAL))
77            .min()
78            .expect("the fixed poll-interval deadline is always present");
79
80        let recv_result = tokio::select! {
81            events = client.recv() => Some(events),
82            () = tokio::time::sleep_until(tokio::time::Instant::from_std(wake_at)) => None,
83        };
84        if let Some(result) = recv_result {
85            match result {
86                Ok(events) => events.iter().for_each(print_event),
87                Err(err) => {
88                    eprintln!("receive failed: {err}");
89                    break;
90                }
91            }
92        }
93
94        if client
95            .next_send_deadline()
96            .is_some_and(|send_at| Instant::now() >= send_at)
97        {
98            // A failed send retains its prepared probe without advancing the
99            // schedule, so a persistent error (e.g. the interface going
100            // down) would otherwise make this loop retry forever instead of
101            // reporting it.
102            match client.send_probe().await {
103                Ok(events) => events.iter().for_each(print_event),
104                Err(err) => {
105                    eprintln!("send failed: {err}");
106                    break;
107                }
108            }
109        }
110        match client.poll_timeouts() {
111            Ok(events) => events.iter().for_each(print_event),
112            Err(err) => {
113                eprintln!("timeout polling failed: {err}");
114                break;
115            }
116        }
117    }
118
119    match client.close().await {
120        Ok(events) => events.iter().for_each(print_event),
121        Err(err) => eprintln!("close failed: {err}"),
122    }
123}
Source

pub fn poll_timeouts_at( &mut self, now: Instant, ) -> Result<Vec<ClientEvent>, ClientError>

Poll protocol timeouts using the caller’s monotonic timestamp.

Source

pub async fn close(&mut self) -> Result<Vec<ClientEvent>, ClientError>

Send the retained close packet and commit local close exactly once.

DSCP is cleared only after write readiness and immediately before the nonblocking send attempt. A WouldBlock result restores it before the next await, so dropping this future at a suspension point cannot leave an otherwise-open session with cleared DSCP.

Examples found in repository?
examples/tokio_client.rs (line 119)
42async fn run() {
43    let config = ClientConfig {
44        server_addr: "127.0.0.1:2112".to_owned(),
45        duration: Some(Duration::from_secs(2)),
46        interval: Duration::from_millis(200),
47        // A single short attempt keeps this example fast when no server is
48        // reachable; production callers should generally keep the default.
49        open_timeouts: vec![Duration::from_millis(300)],
50        ..Default::default()
51    };
52
53    let mut client = match AsyncClient::connect(config).await {
54        Ok(client) => client,
55        Err(err) => {
56            eprintln!("failed to prepare client socket: {err}");
57            return;
58        }
59    };
60
61    match client.open().await {
62        Ok(outcome) => println!("session opened: {outcome:?}"),
63        Err(err) => {
64            eprintln!("open failed (is a server running at 127.0.0.1:2112?): {err}");
65            return;
66        }
67    }
68
69    while !client.is_run_complete() {
70        // Bound the receive wait by the next send/timeout deadline, rather
71        // than awaiting recv() unconditionally: a lost or rate-limited reply
72        // must not stall pacing or timeout classification indefinitely.
73        let wake_at = client
74            .next_send_deadline()
75            .into_iter()
76            .chain(std::iter::once(Instant::now() + TIMEOUT_POLL_INTERVAL))
77            .min()
78            .expect("the fixed poll-interval deadline is always present");
79
80        let recv_result = tokio::select! {
81            events = client.recv() => Some(events),
82            () = tokio::time::sleep_until(tokio::time::Instant::from_std(wake_at)) => None,
83        };
84        if let Some(result) = recv_result {
85            match result {
86                Ok(events) => events.iter().for_each(print_event),
87                Err(err) => {
88                    eprintln!("receive failed: {err}");
89                    break;
90                }
91            }
92        }
93
94        if client
95            .next_send_deadline()
96            .is_some_and(|send_at| Instant::now() >= send_at)
97        {
98            // A failed send retains its prepared probe without advancing the
99            // schedule, so a persistent error (e.g. the interface going
100            // down) would otherwise make this loop retry forever instead of
101            // reporting it.
102            match client.send_probe().await {
103                Ok(events) => events.iter().for_each(print_event),
104                Err(err) => {
105                    eprintln!("send failed: {err}");
106                    break;
107                }
108            }
109        }
110        match client.poll_timeouts() {
111            Ok(events) => events.iter().for_each(print_event),
112            Err(err) => {
113                eprintln!("timeout polling failed: {err}");
114                break;
115            }
116        }
117    }
118
119    match client.close().await {
120        Ok(events) => events.iter().for_each(print_event),
121        Err(err) => eprintln!("close failed: {err}"),
122    }
123}
Source

pub fn next_send_deadline(&self) -> Option<Instant>

Return the next scheduled probe deadline.

Examples found in repository?
examples/tokio_client.rs (line 74)
42async fn run() {
43    let config = ClientConfig {
44        server_addr: "127.0.0.1:2112".to_owned(),
45        duration: Some(Duration::from_secs(2)),
46        interval: Duration::from_millis(200),
47        // A single short attempt keeps this example fast when no server is
48        // reachable; production callers should generally keep the default.
49        open_timeouts: vec![Duration::from_millis(300)],
50        ..Default::default()
51    };
52
53    let mut client = match AsyncClient::connect(config).await {
54        Ok(client) => client,
55        Err(err) => {
56            eprintln!("failed to prepare client socket: {err}");
57            return;
58        }
59    };
60
61    match client.open().await {
62        Ok(outcome) => println!("session opened: {outcome:?}"),
63        Err(err) => {
64            eprintln!("open failed (is a server running at 127.0.0.1:2112?): {err}");
65            return;
66        }
67    }
68
69    while !client.is_run_complete() {
70        // Bound the receive wait by the next send/timeout deadline, rather
71        // than awaiting recv() unconditionally: a lost or rate-limited reply
72        // must not stall pacing or timeout classification indefinitely.
73        let wake_at = client
74            .next_send_deadline()
75            .into_iter()
76            .chain(std::iter::once(Instant::now() + TIMEOUT_POLL_INTERVAL))
77            .min()
78            .expect("the fixed poll-interval deadline is always present");
79
80        let recv_result = tokio::select! {
81            events = client.recv() => Some(events),
82            () = tokio::time::sleep_until(tokio::time::Instant::from_std(wake_at)) => None,
83        };
84        if let Some(result) = recv_result {
85            match result {
86                Ok(events) => events.iter().for_each(print_event),
87                Err(err) => {
88                    eprintln!("receive failed: {err}");
89                    break;
90                }
91            }
92        }
93
94        if client
95            .next_send_deadline()
96            .is_some_and(|send_at| Instant::now() >= send_at)
97        {
98            // A failed send retains its prepared probe without advancing the
99            // schedule, so a persistent error (e.g. the interface going
100            // down) would otherwise make this loop retry forever instead of
101            // reporting it.
102            match client.send_probe().await {
103                Ok(events) => events.iter().for_each(print_event),
104                Err(err) => {
105                    eprintln!("send failed: {err}");
106                    break;
107                }
108            }
109        }
110        match client.poll_timeouts() {
111            Ok(events) => events.iter().for_each(print_event),
112            Err(err) => {
113                eprintln!("timeout polling failed: {err}");
114                break;
115            }
116        }
117    }
118
119    match client.close().await {
120        Ok(events) => events.iter().for_each(print_event),
121        Err(err) => eprintln!("close failed: {err}"),
122    }
123}
Source

pub fn probe_timeout(&self) -> Duration

Return the configured local probe timeout.

Source

pub fn is_run_complete(&self) -> bool

Return whether the current run has completed.

Examples found in repository?
examples/tokio_client.rs (line 69)
42async fn run() {
43    let config = ClientConfig {
44        server_addr: "127.0.0.1:2112".to_owned(),
45        duration: Some(Duration::from_secs(2)),
46        interval: Duration::from_millis(200),
47        // A single short attempt keeps this example fast when no server is
48        // reachable; production callers should generally keep the default.
49        open_timeouts: vec![Duration::from_millis(300)],
50        ..Default::default()
51    };
52
53    let mut client = match AsyncClient::connect(config).await {
54        Ok(client) => client,
55        Err(err) => {
56            eprintln!("failed to prepare client socket: {err}");
57            return;
58        }
59    };
60
61    match client.open().await {
62        Ok(outcome) => println!("session opened: {outcome:?}"),
63        Err(err) => {
64            eprintln!("open failed (is a server running at 127.0.0.1:2112?): {err}");
65            return;
66        }
67    }
68
69    while !client.is_run_complete() {
70        // Bound the receive wait by the next send/timeout deadline, rather
71        // than awaiting recv() unconditionally: a lost or rate-limited reply
72        // must not stall pacing or timeout classification indefinitely.
73        let wake_at = client
74            .next_send_deadline()
75            .into_iter()
76            .chain(std::iter::once(Instant::now() + TIMEOUT_POLL_INTERVAL))
77            .min()
78            .expect("the fixed poll-interval deadline is always present");
79
80        let recv_result = tokio::select! {
81            events = client.recv() => Some(events),
82            () = tokio::time::sleep_until(tokio::time::Instant::from_std(wake_at)) => None,
83        };
84        if let Some(result) = recv_result {
85            match result {
86                Ok(events) => events.iter().for_each(print_event),
87                Err(err) => {
88                    eprintln!("receive failed: {err}");
89                    break;
90                }
91            }
92        }
93
94        if client
95            .next_send_deadline()
96            .is_some_and(|send_at| Instant::now() >= send_at)
97        {
98            // A failed send retains its prepared probe without advancing the
99            // schedule, so a persistent error (e.g. the interface going
100            // down) would otherwise make this loop retry forever instead of
101            // reporting it.
102            match client.send_probe().await {
103                Ok(events) => events.iter().for_each(print_event),
104                Err(err) => {
105                    eprintln!("send failed: {err}");
106                    break;
107                }
108            }
109        }
110        match client.poll_timeouts() {
111            Ok(events) => events.iter().for_each(print_event),
112            Err(err) => {
113                eprintln!("timeout polling failed: {err}");
114                break;
115            }
116        }
117    }
118
119    match client.close().await {
120        Ok(events) => events.iter().for_each(print_event),
121        Err(err) => eprintln!("close failed: {err}"),
122    }
123}
Source

pub fn is_peer_closed(&self) -> bool

Return whether an authenticated peer close ended the session.

Trait Implementations§

Source§

impl Debug for AsyncClient

Source§

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

Formats the value using the given formatter. 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<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> 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.