diff --git a/help.html b/help.html index 47fd1e9..0e54e13 100644 --- a/help.html +++ b/help.html @@ -1 +1 @@ -
#[repr(u8)]
-pub enum State {
- Idle,
- BuildingRequest,
- Requested,
- BuildingResponse,
- Responded,
- Canceled,
- // some variants omitted
+State in interchange - Rust Enum interchange::State
source · #[repr(u8)]pub enum State {
+ Idle = 0,
+ BuildingRequest = 1,
+ Requested = 2,
+ BuildingResponse = 3,
+ Responded = 4,
+ Canceled = 12,
}
Expand description
State of the RPC interchange
-Variants§
§Idle
The requester may send a new request.
-§BuildingRequest
The requester is building a request, using the pre-allocated static data as &mut Request
-§Requested
The request is pending either processing by responder or cancelation by requester.
-§BuildingResponse
The responder is building a response, using the pre-allocated static data as &mut Response
+
Variants§
§Idle = 0
The requester may send a new request.
+§BuildingRequest = 1
The requester is building a request, using the pre-allocated static data as &mut Request
+§Requested = 2
The request is pending either processing by responder or cancelation by requester.
+§BuildingResponse = 3
The responder is building a response, using the pre-allocated static data as &mut Response
It may opportunitstically be canceled by requester.
-§Responded
The responder sent a response.
-§Canceled
The requester canceled the request. Responder needs to acknowledge to return to Idle
-state.
-Trait Implementations§
source§impl PartialEq<State> for State
source§impl PartialEq<u8> for State
source§impl Copy for State
source§impl Eq for State
source§impl StructuralEq for State
source§impl StructuralPartialEq for State
Auto Trait Implementations§
§impl RefUnwindSafe for State
§impl Send for State
§impl Sync for State
§impl Unpin for State
§impl UnwindSafe for State
Blanket Implementations§
source§impl<T, U> Into<U> for Twhere
- U: From<T>,
Trait Implementations§
source§impl PartialEq<u8> for State
source§impl PartialEq for State
source§impl Copy for State
source§impl Eq for State
source§impl StructuralPartialEq for State
Auto Trait Implementations§
§impl Freeze for State
§impl RefUnwindSafe for State
§impl Send for State
§impl Sync for State
§impl Unpin for State
§impl UnwindSafe for State
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
+ T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
\ No newline at end of file
+From<T> for U
chooses to do.
+
Implement a somewhat convenient and somewhat efficient way to perform RPC +
Implement a somewhat convenient and somewhat efficient way to perform RPC in an embedded context.
The approach is inspired by Go’s channels, with the restriction that there is a clear separation into a requester and a responder.
Requests may be canceled, which the responder should honour on a best-effort basis.
-It is assumed that all requests fit in a single Request
enum, and that
-all responses fit in single Response
enum. The Channel
and Interchange
structs allocate a single buffer in which either Request or Response fit and handle synchronization
+all responses fit in single Response
enum. The Channel
and Interchange
structs allocate a single buffer in which either Request or Response fit and handle synchronization
Both structures have const
constructors, allowing them to be statically allocated.
An alternative approach would be to use two heapless Queues of length one each for response and requests. The advantage of our construction is to @@ -45,20 +45,20 @@
N
channelsconst N: usize
generic parameter
-Obtained using Interchange::as_interchange_ref
N
channelsconst N: usize
generic parameter
+Obtained using Interchange::as_interchange_ref
pub struct Channel<Rq, Rp> { /* private fields */ }
Channel used for Request/Response mechanism.
+pub struct Channel<Rq, Rp> { /* private fields */ }
Channel used for Request/Response mechanism.
#[derive(Clone, Debug, PartialEq)]
pub enum Request {
@@ -23,20 +23,20 @@
assert!(rq.request(request).is_ok());
let request = rp.take_request().unwrap();
-println!("rp got request: {:?}", request);
+println!("rp got request: {:?}", request);
let response = Response::There(-1);
assert!(!rp.is_canceled());
assert!(rp.respond(response).is_ok());
let response = rq.take_response().unwrap();
-println!("rq got response: {:?}", response);
+println!("rq got response: {:?}", response);
// early cancelation path
assert!(rq.request(request).is_ok());
let request = rq.cancel().unwrap().unwrap();
-println!("responder could cancel: {:?}", request);
+println!("responder could cancel: {:?}", request);
assert!(rp.take_request().is_none());
assert!(State::Idle == rq.state());
@@ -45,7 +45,7 @@
assert!(rq.request(request).is_ok());
let request = rp.take_request().unwrap();
-println!("responder could cancel: {:?}", &rq.cancel().unwrap().is_none());
+println!("responder could cancel: {:?}", &rq.cancel().unwrap().is_none());
assert!(rp.is_canceled());
assert!(rp.respond(response).is_err());
assert!(rp.acknowledge_cancel().is_ok());
@@ -62,7 +62,7 @@
assert!(rq.send_request().is_ok());
let request = rp.take_request().unwrap();
assert_eq!(request, Request::This(1, 2));
-println!("rp got request: {:?}", request);
+println!("rp got request: {:?}", request);
// building into response buffer
impl Default for Response {
@@ -76,28 +76,28 @@
let response = rq.take_response().unwrap();
assert_eq!(response, Response::Here(3,2,1));
Obtain the requester end of the channel if it hasn’t been taken yet.
-Can be called again if the previously obtained Requester
has been dropped
Obtain the requester end of the channel if it hasn’t been taken yet.
+Can be called again if the previously obtained Requester
has been dropped
From<T> for U
chooses to do.
+pub struct Error;
Calls U::from(self)
.
pub struct Error;
From<T> for U
chooses to do.
+pub struct Interchange<Rq, Rp, const N: usize> { /* private fields */ }
Set of N
channels
pub struct Interchange<Rq, Rp, const N: usize> { /* private fields */ }
Set of N
channels
Channels can be claimed with claim()
static interchange: Interchange<Request, Response,10> = Interchange::new();
for i in 0..10 {
- let rq: Requester<'_, Request, Response>;
- let rp: Responder<'_, Request, Response>;
+ let rq: Requester<'_, Request, Response>;
+ let rp: Responder<'_, Request, Response>;
(rq, rp) = interchange.claim().unwrap() ;
}
Claim one of the channels of the interchange. Returns None if called more than N
times.
Returns a reference to the interchange with the N
const-generic removed.
+
Claim one of the channels of the interchange. Returns None if called more than N
times.
Returns a reference to the interchange with the N
const-generic removed.
This can avoid the requirement to have const N: usize
everywhere
static INTERCHANGE_INNER: Interchange<Request, Response, 1> = Interchange::new();
// The size of the interchange is absent from the type
-static INTERCHANGE: InterchangeRef<'static, Request, Response> = INTERCHANGE_INNER.as_interchange_ref();
+static INTERCHANGE: InterchangeRef<'static, Request, Response> = INTERCHANGE_INNER.as_interchange_ref();
let (mut rq, mut rp) = INTERCHANGE.claim().unwrap();
From<T> for U
chooses to do.
+pub struct InterchangeRef<'alloc, Rq, Rp> { /* private fields */ }
Interchange witout the const N: usize
generic parameter
+
pub struct InterchangeRef<'alloc, Rq, Rp> { /* private fields */ }
Interchange witout the const N: usize
generic parameter
Obtained using Interchange::as_interchange_ref
From<T> for U
chooses to do.
+pub struct Requester<'i, Rq, Rp> { /* private fields */ }
Requester end of a channel
-For a static
Channel
or Interchange
,
+
pub struct Requester<'i, Rq, Rp> { /* private fields */ }
Requester end of a channel
+For a static
Channel
or Interchange
,
the requester uses a 'static
lifetime parameter
Current state of the channel.
Informational only!
The responder may change this state between calls, internally atomics ensure correctness.
-Send a request to the responder.
If efficiency is a concern, or requests need multiple steps to
construct, use request_mut
and `send_request.
If the RPC state is Idle
, this always succeeds, else calling
is a logic error and the request is returned.
Attempt to cancel a request.
If the responder has not taken the request yet, this succeeds and returns the request.
If the responder has taken the request (is processing), we succeed and return None.
In other cases (Idle
or Reponsed
) there is nothing to cancel and we fail.
If there is a response waiting, obtain a reference to it
+If there is a response waiting, obtain a reference to it
This may be called multiple times.
-If there is a request waiting, perform an operation with a reference to it
+If there is a request waiting, perform an operation with a reference to it
This may be called multiple times.
-Look for a response. +
Look for a response. If the responder has sent a response, we return it.
This may be called only once as it move the state to Idle. If you need copies, clone the request.
-Initialize a request with its default values and mutates it with f
Initialize a request with its default values and mutates it with f
This is usefull to build large structures in-place
-Initialize a request with its default values and and return a mutable reference to it
+Initialize a request with its default values and and return a mutable reference to it
This is usefull to build large structures in-place
-Send a request that was already placed in the channel using request_mut
or
+
Send a request that was already placed in the channel using request_mut
or
with_request_mut
.
From<T> for U
chooses to do.
+pub struct Responder<'i, Rq, Rp> { /* private fields */ }
Responder end of a channel
-For a static
Channel
or Interchange
,
+
pub struct Responder<'i, Rq, Rp> { /* private fields */ }
Responder end of a channel
+For a static
Channel
or Interchange
,
the responder uses a 'static
lifetime parameter
Current state of the channel.
Informational only!
The responder may change this state between calls, internally atomics ensure correctness.
-If there is a request waiting, perform an operation with a reference to it
+If there is a request waiting, perform an operation with a reference to it
This may be called only once as it move the state to BuildingResponse.
If you need copies, use take_request
If there is a request waiting, obtain a reference to it
+If there is a request waiting, obtain a reference to it
This may be called multiple times.
-If there is a request waiting, take a reference to it out
+If there is a request waiting, take a reference to it out
This may be called only once as it move the state to BuildingResponse. If you need copies, clone the request.
-Initialize a response with its default values and mutates it with f
Initialize a response with its default values and mutates it with f
This is usefull to build large structures in-place
-Initialize a response with its default values and and return a mutable reference to it
+Initialize a response with its default values and and return a mutable reference to it
This is usefull to build large structures in-place
-Send a response that was already placed in the channel using response_mut
or
+
Send a response that was already placed in the channel using response_mut
or
with_response_mut
.
From<T> for U
chooses to do.
+N
channels","Interchange witout the const N: usize
generic parameter …","The request is pending either processing by responder or …","Requester end of a channel","The responder sent a response.","Responder end of a channel","State of the RPC interchange","","Returns a reference to the interchange with the N
…","","","","","","","","","","","","","","","Attempt to cancel a request.","Claim one of the channels of the interchange. Returns None …","Claim one of the channels of the interchange. Returns None …","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","","Create a new Interchange","Send a request to the responder.","If there is a request waiting, obtain a reference to it","Initialize a request with its default values and and …","Obtain the requester end of the channel if it hasn’t …","Respond to a request.","Obtain the responder end of the channel if it hasn’t …","If there is a response waiting, obtain a reference to it","Initialize a response with its default values and and …","Send a request that was already placed in the channel …","Send a response that was already placed in the channel …","Obtain both the requester and responder ends of the …","Current state of the channel.","Current state of the channel.","If there is a request waiting, take a reference to it out","Look for a response. If the responder has sent a response, …","","","","","","","","","","","","","","","","","","","","","","If there is a request waiting, perform an operation with a …","Initialize a request with its default values and mutates …","If there is a request waiting, perform an operation with a …","Initialize a response with its default values and mutates …"],"i":[8,8,8,0,0,8,0,0,8,0,8,0,0,1,4,9,6,1,4,5,2,8,9,6,1,4,5,2,8,6,4,5,2,8,9,4,6,1,8,8,2,8,9,6,1,4,5,2,8,8,9,6,1,4,5,2,8,1,9,4,6,1,6,9,1,9,6,1,6,1,9,6,1,1,6,9,6,1,4,5,2,8,9,6,1,4,5,2,8,9,6,1,4,5,2,8,1,6,6,1],"f":[0,0,0,0,0,0,0,0,0,0,0,0,0,[1,[[3,[2]]]],[4,5],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[6,[[3,[7,2]]]],[4,7],[5,7],[2,2],[8,8],[[],9],[[],4],[6],[1],[[8,10],11],[[8,8],11],[[2,12],13],[[8,12],13],[[]],[[]],[[]],[[]],[[]],[[]],[10,8],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[1,11],[[],9],[[],4],[6,[[3,[2]]]],[1,[[3,[2]]]],[[[6,[14]]],[[3,[14,2]]]],[9,[[7,[6]]]],[1,[[3,[2]]]],[9,[[7,[1]]]],[6,[[3,[2]]]],[[[1,[14]]],[[3,[14,2]]]],[[[6,[14]]],[[3,[2]]]],[[[1,[14]]],[[3,[2]]]],[9,7],[6,8],[1,8],[1,7],[6,7],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],3],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[],15],[[1,16],[[3,[2]]]],[[[6,[14]],16],[[3,[2]]]],[[6,16],[[3,[2]]]],[[[1,[14]],16],[[3,[2]]]]],"c":[],"p":[[3,"Responder"],[3,"Error"],[4,"Result"],[3,"Interchange"],[3,"InterchangeRef"],[3,"Requester"],[4,"Option"],[4,"State"],[3,"Channel"],[15,"u8"],[15,"bool"],[3,"Formatter"],[6,"Result"],[8,"Default"],[3,"TypeId"],[8,"FnOnce"]]}\
-}');
-if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)};
-if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex};
+var searchIndex = new Map(JSON.parse('[\
+["interchange",{"t":"PPPFFPFFPFPFGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN","n":["BuildingRequest","BuildingResponse","Canceled","Channel","Error","Idle","Interchange","InterchangeRef","Requested","Requester","Responded","Responder","State","acknowledge_cancel","as_interchange_ref","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","cancel","channel","channel","claim","claim","clone","clone","default","default","drop","drop","eq","eq","fmt","fmt","from","from","from","from","from","from","from","from","into","into","into","into","into","into","into","is_canceled","new","new","request","request","request_mut","requester","respond","responder","response","response_mut","send_request","send_response","split","state","state","take_request","take_response","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","with_request","with_request_mut","with_response","with_response_mut"],"q":[[0,"interchange"],[102,"core::result"],[103,"core::option"],[104,"core::fmt"],[105,"core::default"],[106,"core::any"],[107,"core::ops::function"]],"i":[11,11,11,0,0,11,0,0,11,0,11,0,0,1,5,9,7,1,5,6,3,11,9,7,1,5,6,3,11,7,7,1,5,6,3,11,9,5,7,1,11,11,3,11,9,7,1,5,6,3,11,11,9,7,1,5,6,3,11,1,9,5,7,1,7,9,1,9,7,1,7,1,9,7,1,1,7,9,7,1,5,6,3,11,9,7,1,5,6,3,11,9,7,1,5,6,3,11,1,7,7,1],"f":"`````````````{{{b{ce}}}{{h{df}}}{}{}}{{{j{ce}}}{{l{ce}}}{}{}}{ce{}{}}0000000000000{{{n{ce}}}{{h{{A`{c}}f}}}{}{}}{{{n{ce}}}{{Ab{ce}}}{}{}}{{{b{ce}}}{{Ab{ce}}}{}{}}{{{j{ce}}}{{A`{{Ad{{n{ce}}{b{ce}}}}}}}{}{}}{{{l{ce}}}{{A`{{Ad{{n{ce}}{b{ce}}}}}}}{}{}}{ff}{AfAf}{{}{{Ab{ce}}}{}{}}{{}{{j{ce}}}{}{}}{{{n{ce}}}d{}{}}{{{b{ce}}}d{}{}}{{AfAh}Aj}{{AfAf}Aj}{{fAl}An}{{AfAl}An}{cc{}}00000{AhAf}1{ce{}{}}000000{{{b{ce}}}Aj{}{}};:{{{n{ce}}c}{{h{df}}}{}{}}{{{b{ce}}}{{h{cf}}}{}{}}{{{n{ce}}}{{h{cf}}}B`{}}{{{Ab{ce}}}{{A`{{n{ce}}}}}{}{}}{{{b{ce}}e}{{h{df}}}{}{}}{{{Ab{ce}}}{{A`{{b{ce}}}}}{}{}}{{{n{ce}}}{{h{ef}}}{}{}}{{{b{ce}}}{{h{ef}}}{}B`}{{{n{ce}}}{{h{df}}}B`{}}{{{b{ce}}}{{h{df}}}{}B`}{{{Ab{ce}}}{{A`{{Ad{{n{ce}}{b{ce}}}}}}}{}{}}{{{n{ce}}}Af{}{}}{{{b{ce}}}Af{}{}}{{{b{ce}}}{{A`{c}}}{}{}}{{{n{ce}}}{{A`{e}}}{}{}}{c{{h{e}}}{}{}}0000000000000{cBb{}}000000{{{b{ce}}i}{{h{gf}}}{}{}{}{{Bf{c}{{Bd{g}}}}}}{{{n{ce}}i}{{h{gf}}}B`{}{}{{Bf{c}{{Bd{g}}}}}}{{{n{ce}}i}{{h{gf}}}{}{}{}{{Bf{e}{{Bd{g}}}}}}{{{b{ce}}i}{{h{gf}}}{}B`{}{{Bf{e}{{Bd{g}}}}}}","D":"Fd","p":[[5,"Responder",0],[1,"unit"],[5,"Error",0],[6,"Result",102],[5,"Interchange",0],[5,"InterchangeRef",0],[5,"Requester",0],[6,"Option",103],[5,"Channel",0],[1,"tuple"],[6,"State",0],[1,"u8"],[1,"bool"],[5,"Formatter",104],[8,"Result",104],[10,"Default",105],[5,"TypeId",106],[17,"Output"],[10,"FnOnce",107]],"r":[],"b":[[40,"impl-PartialEq%3Cu8%3E-for-State"],[41,"impl-PartialEq-for-State"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAADQACQADAAAABQAAAA4AAAAQAA0AHwABACMACQAzAAAAPAABAE4AFAA="}]\
+]'));
+if (typeof exports !== 'undefined') exports.searchIndex = searchIndex;
+else if (window.initSearch) window.initSearch(searchIndex);
diff --git a/search.desc/interchange/interchange-desc-0-.js b/search.desc/interchange/interchange-desc-0-.js
new file mode 100644
index 0000000..9534836
--- /dev/null
+++ b/search.desc/interchange/interchange-desc-0-.js
@@ -0,0 +1 @@
+searchState.loadedDescShard("interchange", 0, "Implement a somewhat convenient and somewhat efficient way …\nThe requester is building a request, using the …\nThe responder is building a response, using the …\nChannel used for Request/Response mechanism.\nThe requester may send a new request.\nSet of N
channels\nInterchange witout the const N: usize
generic parameter …\nThe request is pending either processing by responder or …\nRequester end of a channel\nThe responder sent a response.\nResponder end of a channel\nState of the RPC interchange\nReturns a reference to the interchange with the N
…\nAttempt to cancel a request.\nClaim one of the channels of the interchange. Returns None …\nClaim one of the channels of the interchange. Returns None …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self)
.\nCalls U::from(self)
.\nCalls U::from(self)
.\nCalls U::from(self)
.\nCalls U::from(self)
.\nCalls U::from(self)
.\nCalls U::from(self)
.\nCreate a new Interchange\nSend a request to the responder.\nIf there is a request waiting, obtain a reference to it\nInitialize a request with its default values and and …\nObtain the requester end of the channel if it hasn’t …\nRespond to a request.\nObtain the responder end of the channel if it hasn’t …\nIf there is a response waiting, obtain a reference to it\nInitialize a response with its default values and and …\nSend a request that was already placed in the channel …\nSend a response that was already placed in the channel …\nObtain both the requester and responder ends of the …\nCurrent state of the channel.\nCurrent state of the channel.\nIf there is a request waiting, take a reference to it out\nLook for a response. If the responder has sent a response, …\nIf there is a request waiting, perform an operation with a …\nInitialize a request with its default values and mutates …\nIf there is a request waiting, perform an operation with a …\nInitialize a response with its default values and mutates …")
\ No newline at end of file
diff --git a/settings.html b/settings.html
index 5fc9d25..3de1f14 100644
--- a/settings.html
+++ b/settings.html
@@ -1 +1 @@
-1 +lib.rs - source \ No newline at end of file diff --git a/static.files/ayu-614652228113ac93.css b/static.files/ayu-614652228113ac93.css deleted file mode 100644 index 8fd09c9..0000000 --- a/static.files/ayu-614652228113ac93.css +++ /dev/null @@ -1 +0,0 @@ - :root{--main-background-color:#0f1419;--main-color:#c5c5c5;--settings-input-color:#ffb454;--settings-input-border-color:#999;--settings-button-color:#fff;--settings-button-border-focus:#e0e0e0;--sidebar-background-color:#14191f;--sidebar-background-color-hover:rgba(70,70,70,0.33);--code-block-background-color:#191f26;--scrollbar-track-background-color:transparent;--scrollbar-thumb-background-color:#5c6773;--scrollbar-color:#5c6773 #24292f;--headings-border-bottom-color:#5c6773;--border-color:#5c6773;--button-background-color:#141920;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#5c6773;--copy-path-button-color:#fff;--copy-path-img-filter:invert(70%);--copy-path-img-hover-filter:invert(100%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--type-link-color:#ffa0a5;--trait-link-color:#39afd7;--assoc-item-link-color:#39afd7;--function-link-color:#fdd687;--macro-link-color:#a37acc;--keyword-link-color:#39afd7;--mod-link-color:#39afd7;--link-color:#39afd7;--sidebar-link-color:#53b1db;--sidebar-current-link-background-color:transparent;--search-result-link-focus-background-color:#3c3c3c;--search-result-border-color:#aaa3;--search-color:#fff;--search-error-code-background-color:#4f4c4c;--search-results-alias-color:#c5c5c5;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:none;--search-tab-button-not-selected-background:transparent !important;--search-tab-button-selected-border-top-color:none;--search-tab-button-selected-background:#141920 !important;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ff7733;--code-highlight-kw-2-color:#ff7733;--code-highlight-lifetime-color:#ff7733;--code-highlight-prelude-color:#69f2df;--code-highlight-prelude-val-color:#ff7733;--code-highlight-number-color:#b8cc52;--code-highlight-string-color:#b8cc52;--code-highlight-literal-color:#ff7733;--code-highlight-attribute-color:#e6e1cf;--code-highlight-self-color:#36a3d9;--code-highlight-macro-color:#a37acc;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#788797;--code-highlight-doc-comment-color:#a1ac88;--src-line-numbers-span-color:#5c6773;--src-line-number-highlighted-background-color:rgba(255,236,164,0.06);--test-arrow-color:#788797;--test-arrow-background-color:rgba(57,175,215,0.09);--test-arrow-hover-color:#c5c5c5;--test-arrow-hover-background-color:rgba(57,175,215,0.368);--target-background-color:rgba(255,236,164,0.06);--target-border-color:rgba(255,180,76,0.85);--kbd-color:#c5c5c5;--kbd-background:#314559;--kbd-box-shadow-color:#5c6773;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg) brightness(94%) contrast(94%);--crate-search-div-hover-filter:invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg) brightness(113%) contrast(76%);--crate-search-hover-border:#e0e0e0;--source-sidebar-background-selected:#14191f;--source-sidebar-background-hover:#14191f;--table-alt-row-background-color:#191f26;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:rgb(91,59,1);--scrape-example-code-line-highlight-focus:rgb(124,75,15);--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(15,20,25,1);--scrape-example-code-wrapper-background-end:rgba(15,20,25,0);}h1,h2,h3,h4,h1 a,.sidebar h2 a,.sidebar h3 a,#source-sidebar>.title{color:#fff;}h4{border:none;}.docblock code{color:#ffb454;}.docblock a>code{color:#39AFD7 !important;}.code-header,.docblock pre>code,pre,pre>code,.item-info code,.rustdoc.source .example-wrap{color:#e6e1cf;}.sidebar .current,.sidebar a:hover,#source-sidebar div.files>a:hover,details.dir-entry summary:hover,#source-sidebar div.files>a:focus,details.dir-entry summary:focus,#source-sidebar div.files>a.selected{color:#ffb44c;}.sidebar-elems .location{color:#ff7733;}.src-line-numbers .line-highlighted{color:#708090;padding-right:7px;border-right:1px solid #ffb44c;}.search-results a:hover,.search-results a:focus{color:#fff !important;background-color:#3c3c3c;}.search-results a{color:#0096cf;}.search-results a div.desc{color:#c5c5c5;}.result-name .primitive>i,.result-name .keyword>i{color:#788797;}#search-tabs>button.selected{border-bottom:1px solid #ffb44c !important;border-top:none;}#search-tabs>button:not(.selected){border:none;background-color:transparent !important;}#search-tabs>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}#settings-menu>a img{filter:invert(100);} \ No newline at end of file diff --git a/static.files/clipboard-7571035ce49a181d.svg b/static.files/clipboard-24048e6d87f63d07.svg similarity index 88% rename from static.files/clipboard-7571035ce49a181d.svg rename to static.files/clipboard-24048e6d87f63d07.svg index 8adbd99..e437c83 100644 --- a/static.files/clipboard-7571035ce49a181d.svg +++ b/static.files/clipboard-24048e6d87f63d07.svg @@ -1 +1 @@ - + diff --git a/static.files/dark-1097f8e92a01e3cf.css b/static.files/dark-1097f8e92a01e3cf.css deleted file mode 100644 index 1e5e7d1..0000000 --- a/static.files/dark-1097f8e92a01e3cf.css +++ /dev/null @@ -1 +0,0 @@ -:root{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--source-sidebar-background-selected:#333;--source-sidebar-background-hover:#444;--table-alt-row-background-color:#2A2A2A;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:rgb(91,59,1);--scrape-example-code-line-highlight-focus:rgb(124,75,15);--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);} \ No newline at end of file diff --git a/static.files/favicon-16x16-8b506e7a72182f1c.png b/static.files/favicon-16x16-8b506e7a72182f1c.png deleted file mode 100644 index ea4b45c..0000000 Binary files a/static.files/favicon-16x16-8b506e7a72182f1c.png and /dev/null differ diff --git a/static.files/light-0f8c037637f9eb3e.css b/static.files/light-0f8c037637f9eb3e.css deleted file mode 100644 index 21c3a85..0000000 --- a/static.files/light-0f8c037637f9eb3e.css +++ /dev/null @@ -1 +0,0 @@ -:root{--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#F5F5F5;--sidebar-background-color-hover:#E0E0E0;--code-block-background-color:#F5F5F5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#ffffff;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--source-sidebar-background-selected:#fff;--source-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#F5F5F5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);} \ No newline at end of file diff --git a/static.files/main-20a3ad099b048cf2.js b/static.files/main-20a3ad099b048cf2.js new file mode 100644 index 0000000..133116e --- /dev/null +++ b/static.files/main-20a3ad099b048cf2.js @@ -0,0 +1,11 @@ +"use strict";window.RUSTDOC_TOOLTIP_HOVER_MS=300;window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS=450;function resourcePath(basename,extension){return getVar("root-path")+basename+getVar("resource-suffix")+extension}function hideMain(){addClass(document.getElementById(MAIN_ID),"hidden")}function showMain(){removeClass(document.getElementById(MAIN_ID),"hidden")}function blurHandler(event,parentElem,hideCallback){if(!parentElem.contains(document.activeElement)&&!parentElem.contains(event.relatedTarget)){hideCallback()}}window.rootPath=getVar("root-path");window.currentCrate=getVar("current-crate");function setMobileTopbar(){const mobileTopbar=document.querySelector(".mobile-topbar");const locationTitle=document.querySelector(".sidebar h2.location");if(mobileTopbar){const mobileTitle=document.createElement("h2");mobileTitle.className="location";if(hasClass(document.querySelector(".rustdoc"),"crate")){mobileTitle.innerHTML=`Crate ${window.currentCrate}`}else if(locationTitle){mobileTitle.innerHTML=locationTitle.innerHTML}mobileTopbar.appendChild(mobileTitle)}}function getVirtualKey(ev){if("key"in ev&&typeof ev.key!=="undefined"){return ev.key}const c=ev.charCode||ev.keyCode;if(c===27){return"Escape"}return String.fromCharCode(c)}const MAIN_ID="main-content";const SETTINGS_BUTTON_ID="settings-menu";const ALTERNATIVE_DISPLAY_ID="alternative-display";const NOT_DISPLAYED_ID="not-displayed";const HELP_BUTTON_ID="help-button";function getSettingsButton(){return document.getElementById(SETTINGS_BUTTON_ID)}function getHelpButton(){return document.getElementById(HELP_BUTTON_ID)}function getNakedUrl(){return window.location.href.split("?")[0].split("#")[0]}function insertAfter(newNode,referenceNode){referenceNode.parentNode.insertBefore(newNode,referenceNode.nextSibling)}function getOrCreateSection(id,classes){let el=document.getElementById(id);if(!el){el=document.createElement("section");el.id=id;el.className=classes;insertAfter(el,document.getElementById(MAIN_ID))}return el}function getAlternativeDisplayElem(){return getOrCreateSection(ALTERNATIVE_DISPLAY_ID,"content hidden")}function getNotDisplayedElem(){return getOrCreateSection(NOT_DISPLAYED_ID,"hidden")}function switchDisplayedElement(elemToDisplay){const el=getAlternativeDisplayElem();if(el.children.length>0){getNotDisplayedElem().appendChild(el.firstElementChild)}if(elemToDisplay===null){addClass(el,"hidden");showMain();return}el.appendChild(elemToDisplay);hideMain();removeClass(el,"hidden")}function browserSupportsHistoryApi(){return window.history&&typeof window.history.pushState==="function"}function preLoadCss(cssUrl){const link=document.createElement("link");link.href=cssUrl;link.rel="preload";link.as="style";document.getElementsByTagName("head")[0].appendChild(link)}(function(){const isHelpPage=window.location.pathname.endsWith("/help.html");function loadScript(url,errorCallback){const script=document.createElement("script");script.src=url;if(errorCallback!==undefined){script.onerror=errorCallback}document.head.append(script)}getSettingsButton().onclick=event=>{if(event.ctrlKey||event.altKey||event.metaKey){return}window.hideAllModals(false);addClass(getSettingsButton(),"rotate");event.preventDefault();loadScript(getVar("static-root-path")+getVar("settings-js"));setTimeout(()=>{const themes=getVar("themes").split(",");for(const theme of themes){if(theme!==""){preLoadCss(getVar("root-path")+theme+".css")}}},0)};window.searchState={loadingText:"Loading search results...",input:document.getElementsByClassName("search-input")[0],outputElement:()=>{let el=document.getElementById("search");if(!el){el=document.createElement("section");el.id="search";getNotDisplayedElem().appendChild(el)}return el},title:document.title,titleBeforeSearch:document.title,timeout:null,currentTab:0,focusedByTab:[null,null,null],clearInputTimeout:()=>{if(searchState.timeout!==null){clearTimeout(searchState.timeout);searchState.timeout=null}},isDisplayed:()=>searchState.outputElement().parentElement.id===ALTERNATIVE_DISPLAY_ID,focus:()=>{searchState.input.focus()},defocus:()=>{searchState.input.blur()},showResults:search=>{if(search===null||typeof search==="undefined"){search=searchState.outputElement()}switchDisplayedElement(search);searchState.mouseMovedAfterSearch=false;document.title=searchState.title},removeQueryParameters:()=>{document.title=searchState.titleBeforeSearch;if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.hash)}},hideResults:()=>{switchDisplayedElement(null);searchState.removeQueryParameters()},getQueryStringParams:()=>{const params={};window.location.search.substring(1).split("&").map(s=>{const pair=s.split("=").map(x=>x.replace(/\+/g," "));params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1])});return params},setup:()=>{const search_input=searchState.input;if(!searchState.input){return}let searchLoaded=false;function sendSearchForm(){document.getElementsByClassName("search-form")[0].submit()}function loadSearch(){if(!searchLoaded){searchLoaded=true;loadScript(getVar("static-root-path")+getVar("search-js"),sendSearchForm);loadScript(resourcePath("search-index",".js"),sendSearchForm)}}search_input.addEventListener("focus",()=>{search_input.origPlaceholder=search_input.placeholder;search_input.placeholder="Type your search here.";loadSearch()});if(search_input.value!==""){loadSearch()}const params=searchState.getQueryStringParams();if(params.search!==undefined){searchState.setLoadingSearch();loadSearch()}},setLoadingSearch:()=>{const search=searchState.outputElement();search.innerHTML=" #![cfg_attr(not(test), no_std)] //! Implement a somewhat convenient and somewhat efficient way to perform RPC //! in an embedded context. //! -//! The approach is inspired by Go's channels, with the restriction that +//! The approach is inspired by Go's channels, with the restriction that //! there is a clear separation into a requester and a responder. //! //! Requests may be canceled, which the responder should honour on a @@ -1176,7 +1177,7 @@ //! //! ### Approach //! It is assumed that all requests fit in a single `Request` enum, and that -//! all responses fit in single `Response` enum. The [`Channel`](Channel) and [`Interchange`](Interchange) structs allocate a single buffer in which either Request or Response fit and handle synchronization +//! all responses fit in single `Response` enum. The [`Channel`]() and [`Interchange`]() structs allocate a single buffer in which either Request or Response fit and handle synchronization //! Both structures have `const` constructors, allowing them to be statically allocated. //! //! An alternative approach would be to use two heapless Queues of length one @@ -1209,20 +1210,20 @@ //! assert!(rq.request(request).is_ok()); //! //! let request = rp.take_request().unwrap(); -//! println!("rp got request: {:?}", request); +//! println!("rp got request: {:?}", request); //! //! let response = Response::There(-1); //! assert!(!rp.is_canceled()); //! assert!(rp.respond(response).is_ok()); //! //! let response = rq.take_response().unwrap(); -//! println!("rq got response: {:?}", response); +//! println!("rq got response: {:?}", response); //! //! // early cancelation path //! assert!(rq.request(request).is_ok()); //! //! let request = rq.cancel().unwrap().unwrap(); -//! println!("responder could cancel: {:?}", request); +//! println!("responder could cancel: {:?}", request); //! //! assert!(rp.take_request().is_none()); //! assert!(State::Idle == rq.state()); @@ -1231,7 +1232,7 @@ //! assert!(rq.request(request).is_ok()); //! let request = rp.take_request().unwrap(); //! -//! println!("responder could cancel: {:?}", &rq.cancel().unwrap().is_none()); +//! println!("responder could cancel: {:?}", &rq.cancel().unwrap().is_none()); //! assert!(rp.is_canceled()); //! assert!(rp.respond(response).is_err()); //! assert!(rp.acknowledge_cancel().is_ok()); @@ -1248,7 +1249,7 @@ //! assert!(rq.send_request().is_ok()); //! let request = rp.take_request().unwrap(); //! assert_eq!(request, Request::This(1, 2)); -//! println!("rp got request: {:?}", request); +//! println!("rp got request: {:?}", request); //! //! // building into response buffer //! impl Default for Response { @@ -1283,8 +1284,8 @@ pub struct Error; impl Debug for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str("The interchange is busy, this operation could not be performed") + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str("The interchange is busy, this operation could not be performed") } } @@ -1304,13 +1305,7 @@ /// The responder sent a response. Responded = 4, - #[doc(hidden)] - CancelingRequested = 10, - #[doc(hidden)] - CancelingBuildingResponse = 11, - /// The requester canceled the request. Responder needs to acknowledge to return to `Idle` - /// state. - Canceled = 12, + Canceled = 12, } impl PartialEq<u8> for State { @@ -1327,11 +1322,7 @@ 2 => State::Requested, 3 => State::BuildingResponse, 4 => State::Responded, - - 10 => State::CancelingRequested, - 11 => State::CancelingBuildingResponse, 12 => State::Canceled, - _ => State::Idle, } } @@ -1435,20 +1426,20 @@ /// assert!(rq.request(request).is_ok()); /// /// let request = rp.take_request().unwrap(); -/// println!("rp got request: {:?}", request); +/// println!("rp got request: {:?}", request); /// /// let response = Response::There(-1); /// assert!(!rp.is_canceled()); /// assert!(rp.respond(response).is_ok()); /// /// let response = rq.take_response().unwrap(); -/// println!("rq got response: {:?}", response); +/// println!("rq got response: {:?}", response); /// /// // early cancelation path /// assert!(rq.request(request).is_ok()); /// /// let request = rq.cancel().unwrap().unwrap(); -/// println!("responder could cancel: {:?}", request); +/// println!("responder could cancel: {:?}", request); /// /// assert!(rp.take_request().is_none()); /// assert!(State::Idle == rq.state()); @@ -1457,7 +1448,7 @@ /// assert!(rq.request(request).is_ok()); /// let request = rp.take_request().unwrap(); /// -/// println!("responder could cancel: {:?}", &rq.cancel().unwrap().is_none()); +/// println!("responder could cancel: {:?}", &rq.cancel().unwrap().is_none()); /// assert!(rp.is_canceled()); /// assert!(rp.respond(response).is_err()); /// assert!(rp.acknowledge_cancel().is_ok()); @@ -1474,7 +1465,7 @@ /// assert!(rq.send_request().is_ok()); /// let request = rp.take_request().unwrap(); /// assert_eq!(request, Request::This(1, 2)); -/// println!("rp got request: {:?}", request); +/// println!("rp got request: {:?}", request); /// /// // building into response buffer /// impl Default for Response { @@ -1500,7 +1491,7 @@ #[cfg(not(loom))] const CHANNEL_INIT: Channel<Rq, Rp> = Self::new(); - // Loom's atomics are not const :/ + // Loom's atomics are not const :/ #[cfg(not(loom))] pub const fn new() -> Self { Self { @@ -1521,10 +1512,10 @@ } } - /// Obtain the requester end of the channel if it hasn't been taken yet. + /// Obtain the requester end of the channel if it hasn't been taken yet. /// - /// Can be called again if the previously obtained [`Requester`](Requester) has been dropped - pub fn requester(&self) -> Option<Requester<'_, Rq, Rp>> { + /// Can be called again if the previously obtained [`Requester`]() has been dropped + pub fn requester(&self) -> Option<Requester<'_, Rq, Rp>> { if self .requester_claimed .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed) @@ -1536,10 +1527,10 @@ } } - /// Obtain the responder end of the channel if it hasn't been taken yet. + /// Obtain the responder end of the channel if it hasn't been taken yet. /// - /// Can be called again if the previously obtained [`Responder`](Responder) has been dropped - pub fn responder(&self) -> Option<Responder<'_, Rq, Rp>> { + /// Can be called again if the previously obtained [`Responder`]() has been dropped + pub fn responder(&self) -> Option<Responder<'_, Rq, Rp>> { if self .responder_claimed .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed) @@ -1553,10 +1544,16 @@ /// Obtain both the requester and responder ends of the channel. /// - /// Can be called again if the previously obtained [`Responder`](Responder) and [`Requester`](Requester) have been dropped - pub fn split(&self) -> Option<(Requester<'_, Rq, Rp>, Responder<'_, Rq, Rp>)> { + /// Can be called again if the previously obtained [`Responder`]() and [`Requester`]() have been dropped + pub fn split(&self) -> Option<(Requester<'_, Rq, Rp>, Responder<'_, Rq, Rp>)> { Some((self.requester()?, self.responder()?)) } + + fn transition(&self, from: State, to: State) -> bool { + self.state + .compare_exchange(from as u8, to as u8, Ordering::AcqRel, Ordering::Relaxed) + .is_ok() + } } impl<Rq, Rp> Default for Channel<Rq, Rp> { @@ -1567,13 +1564,13 @@ /// Requester end of a channel /// -/// For a `static` [`Channel`](Channel) or [`Interchange`](Interchange), -/// the requester uses a `'static` lifetime parameter -pub struct Requester<'i, Rq, Rp> { - channel: &'i Channel<Rq, Rp>, +/// For a `static` [`Channel`]() or [`Interchange`](), +/// the requester uses a `'static` lifetime parameter +pub struct Requester<'i, Rq, Rp> { + channel: &'i Channel<Rq, Rp>, } -impl<'i, Rq, Rp> Drop for Requester<'i, Rq, Rp> { +impl<'i, Rq, Rp> Drop for Requester<'i, Rq, Rp> { fn drop(&mut self) { self.channel .requester_claimed @@ -1581,13 +1578,9 @@ } } -impl<'i, Rq, Rp> Requester<'i, Rq, Rp> { - #[inline] - fn transition(&self, from: State, to: State) -> bool { +impl<'i, Rq, Rp> Requester<'i, Rq, Rp> { + pub fn channel(&self) -> &'i Channel<Rq, Rp> { self.channel - .state - .compare_exchange(from as u8, to as u8, Ordering::SeqCst, Ordering::SeqCst) - .is_ok() } #[cfg(not(loom))] @@ -1661,23 +1654,17 @@ /// /// In other cases (`Idle` or `Reponsed`) there is nothing to cancel and we fail. pub fn cancel(&mut self) -> Result<Option<Rq>, Error> { - // we canceled before the responder was even aware of the request. - if self.transition(State::Requested, State::CancelingRequested) { - self.channel - .state - .store(State::Idle as u8, Ordering::Release); - return Ok(Some(unsafe { self.with_data_mut(|i| i.take_rq()) })); + if self + .channel + .transition(State::BuildingResponse, State::Canceled) + { + // we canceled after the responder took the request, but before they answered. + return Ok(None); } - // we canceled after the responder took the request, but before they answered. - if self.transition(State::BuildingResponse, State::CancelingRequested) { - // this may not yet be None in case the responder switched state to - // BuildingResponse but did not take out the request yet. - // assert!(self.data.is_none()); - self.channel - .state - .store(State::Canceled as u8, Ordering::Release); - return Ok(None); + if self.channel.transition(State::Requested, State::Idle) { + // we canceled before the responder was even aware of the request. + return Ok(Some(unsafe { self.with_data_mut(|i| i.take_rq()) })); } Err(Error) @@ -1690,7 +1677,7 @@ // this is likely correct #[cfg(not(loom))] pub fn response(&self) -> Result<&Rp, Error> { - if self.transition(State::Responded, State::Responded) { + if self.channel.transition(State::Responded, State::Responded) { Ok(unsafe { self.data().rp_ref() }) } else { Err(Error) @@ -1701,7 +1688,7 @@ /// /// This may be called multiple times. pub fn with_response<R>(&self, f: impl FnOnce(&Rp) -> R) -> Result<R, Error> { - if self.transition(State::Responded, State::Responded) { + if self.channel.transition(State::Responded, State::Responded) { Ok(unsafe { self.with_data(|i| f(i.rp_ref())) }) } else { Err(Error) @@ -1713,10 +1700,10 @@ /// /// This may be called only once as it move the state to Idle. /// If you need copies, clone the request. - // It is a logic error to call this method if we're Idle or Canceled, but + // It is a logic error to call this method if we're Idle or Canceled, but // it seems unnecessary to model this. pub fn take_response(&mut self) -> Option<Rp> { - if self.transition(State::Responded, State::Idle) { + if self.channel.transition(State::Responded, State::Idle) { Some(unsafe { self.with_data_mut(|i| i.take_rp()) }) } else { None @@ -1724,7 +1711,7 @@ } } -impl<'i, Rq, Rp> Requester<'i, Rq, Rp> +impl<'i, Rq, Rp> Requester<'i, Rq, Rp> where Rq: Default, { @@ -1732,8 +1719,10 @@ /// /// This is usefull to build large structures in-place pub fn with_request_mut<R>(&mut self, f: impl FnOnce(&mut Rq) -> R) -> Result<R, Error> { - if self.transition(State::Idle, State::BuildingRequest) - || self.transition(State::BuildingRequest, State::BuildingRequest) + if self.channel.transition(State::Idle, State::BuildingRequest) + || self + .channel + .transition(State::BuildingRequest, State::BuildingRequest) { let res = unsafe { self.with_data_mut(|i| { @@ -1756,8 +1745,10 @@ // this is likely correct #[cfg(not(loom))] pub fn request_mut(&mut self) -> Result<&mut Rq, Error> { - if self.transition(State::Idle, State::BuildingRequest) - || self.transition(State::BuildingRequest, State::BuildingRequest) + if self.channel.transition(State::Idle, State::BuildingRequest) + || self + .channel + .transition(State::BuildingRequest, State::BuildingRequest) { unsafe { self.with_data_mut(|i| { @@ -1776,7 +1767,9 @@ /// `with_request_mut`. pub fn send_request(&mut self) -> Result<(), Error> { if State::BuildingRequest == self.channel.state.load(Ordering::Acquire) - && self.transition(State::BuildingRequest, State::Requested) + && self + .channel + .transition(State::BuildingRequest, State::Requested) { Ok(()) } else { @@ -1788,13 +1781,13 @@ /// Responder end of a channel /// -/// For a `static` [`Channel`](Channel) or [`Interchange`](Interchange), -/// the responder uses a `'static` lifetime parameter -pub struct Responder<'i, Rq, Rp> { - channel: &'i Channel<Rq, Rp>, +/// For a `static` [`Channel`]() or [`Interchange`](), +/// the responder uses a `'static` lifetime parameter +pub struct Responder<'i, Rq, Rp> { + channel: &'i Channel<Rq, Rp>, } -impl<'i, Rq, Rp> Drop for Responder<'i, Rq, Rp> { +impl<'i, Rq, Rp> Drop for Responder<'i, Rq, Rp> { fn drop(&mut self) { self.channel .responder_claimed @@ -1802,13 +1795,9 @@ } } -impl<'i, Rq, Rp> Responder<'i, Rq, Rp> { - #[inline] - fn transition(&self, from: State, to: State) -> bool { +impl<'i, Rq, Rp> Responder<'i, Rq, Rp> { + pub fn channel(&self) -> &'i Channel<Rq, Rp> { self.channel - .state - .compare_exchange(from as u8, to as u8, Ordering::SeqCst, Ordering::SeqCst) - .is_ok() } #[cfg(not(loom))] @@ -1857,7 +1846,10 @@ /// This may be called only once as it move the state to BuildingResponse. /// If you need copies, use `take_request` pub fn with_request<R>(&self, f: impl FnOnce(&Rq) -> R) -> Result<R, Error> { - if self.transition(State::Requested, State::BuildingResponse) { + if self + .channel + .transition(State::Requested, State::BuildingResponse) + { Ok(unsafe { self.with_data(|i| f(i.rq_ref())) }) } else { Err(Error) @@ -1871,7 +1863,10 @@ // this is likely correct #[cfg(not(loom))] pub fn request(&self) -> Result<&Rq, Error> { - if self.transition(State::Requested, State::BuildingResponse) { + if self + .channel + .transition(State::Requested, State::BuildingResponse) + { Ok(unsafe { self.data().rq_ref() }) } else { Err(Error) @@ -1883,7 +1878,10 @@ /// This may be called only once as it move the state to BuildingResponse. /// If you need copies, clone the request. pub fn take_request(&mut self) -> Option<Rq> { - if self.transition(State::Requested, State::BuildingResponse) { + if self + .channel + .transition(State::Requested, State::BuildingResponse) + { Some(unsafe { self.with_data_mut(|i| i.take_rq()) }) } else { None @@ -1899,17 +1897,7 @@ // // It is a logic error to call this method if there is no pending cancellation. pub fn acknowledge_cancel(&self) -> Result<(), Error> { - if self - .channel - .state - .compare_exchange( - State::Canceled as u8, - State::Idle as u8, - Ordering::SeqCst, - Ordering::SeqCst, - ) - .is_ok() - { + if self.channel.transition(State::Canceled, State::Idle) { Ok(()) } else { Err(Error) @@ -1926,17 +1914,21 @@ unsafe { self.with_data_mut(|i| *i = Message::from_rp(response)); } - self.channel - .state - .store(State::Responded as u8, Ordering::Release); - Ok(()) + if self + .channel + .transition(State::BuildingResponse, State::Responded) + { + Ok(()) + } else { + Err(Error) + } } else { Err(Error) } } } -impl<'i, Rq, Rp> Responder<'i, Rq, Rp> +impl<'i, Rq, Rp> Responder<'i, Rq, Rp> where Rp: Default, { @@ -1944,8 +1936,12 @@ /// /// This is usefull to build large structures in-place pub fn with_response_mut<R>(&mut self, f: impl FnOnce(&mut Rp) -> R) -> Result<R, Error> { - if self.transition(State::Requested, State::BuildingResponse) - || self.transition(State::BuildingResponse, State::BuildingResponse) + if self + .channel + .transition(State::Requested, State::BuildingResponse) + || self + .channel + .transition(State::BuildingResponse, State::BuildingResponse) { let res = unsafe { self.with_data_mut(|i| { @@ -1968,8 +1964,12 @@ // this is likely correct #[cfg(not(loom))] pub fn response_mut(&mut self) -> Result<&mut Rp, Error> { - if self.transition(State::Requested, State::BuildingResponse) - || self.transition(State::BuildingResponse, State::BuildingResponse) + if self + .channel + .transition(State::Requested, State::BuildingResponse) + || self + .channel + .transition(State::BuildingResponse, State::BuildingResponse) { unsafe { self.with_data_mut(|i| { @@ -1988,7 +1988,9 @@ /// `with_response_mut`. pub fn send_response(&mut self) -> Result<(), Error> { if State::BuildingResponse == self.channel.state.load(Ordering::Acquire) - && self.transition(State::BuildingResponse, State::Responded) + && self + .channel + .transition(State::BuildingResponse, State::Responded) { Ok(()) } else { @@ -2029,8 +2031,8 @@ /// static interchange: Interchange<Request, Response,10> = Interchange::new(); /// /// for i in 0..10 { -/// let rq: Requester<'_, Request, Response>; -/// let rp: Responder<'_, Request, Response>; +/// let rq: Requester<'_, Request, Response>; +/// let rp: Responder<'_, Request, Response>; /// (rq, rp) = interchange.claim().unwrap() ; /// } /// ``` @@ -2072,11 +2074,11 @@ /// static INTERCHANGE_INNER: Interchange<Request, Response, 1> = Interchange::new(); /// /// // The size of the interchange is absent from the type - /// static INTERCHANGE: InterchangeRef<'static, Request, Response> = INTERCHANGE_INNER.as_interchange_ref(); + /// static INTERCHANGE: InterchangeRef<'static, Request, Response> = INTERCHANGE_INNER.as_interchange_ref(); /// /// let (mut rq, mut rp) = INTERCHANGE.claim().unwrap(); /// ``` - pub const fn as_interchange_ref(&self) -> InterchangeRef<'_, Rq, Rp> { + pub const fn as_interchange_ref(&self) -> InterchangeRef<'_, Rq, Rp> { InterchangeRef { channels: &self.channels, last_claimed: &self.last_claimed, @@ -2086,13 +2088,13 @@ /// Interchange witout the `const N: usize` generic parameter /// Obtained using [`Interchange::as_interchange_ref`](Interchange::as_interchange_ref) -pub struct InterchangeRef<'alloc, Rq, Rp> { - channels: &'alloc [Channel<Rq, Rp>], - last_claimed: &'alloc AtomicUsize, +pub struct InterchangeRef<'alloc, Rq, Rp> { + channels: &'alloc [Channel<Rq, Rp>], + last_claimed: &'alloc AtomicUsize, } -impl<'alloc, Rq, Rp> InterchangeRef<'alloc, Rq, Rp> { +impl<'alloc, Rq, Rp> InterchangeRef<'alloc, Rq, Rp> { /// Claim one of the channels of the interchange. Returns None if called more than `N` times. - pub fn claim(&self) -> Option<(Requester<'alloc, Rq, Rp>, Responder<'alloc, Rq, Rp>)> { + pub fn claim(&self) -> Option<(Requester<'alloc, Rq, Rp>, Responder<'alloc, Rq, Rp>)> { let index = self.last_claimed.fetch_add(1, Ordering::Relaxed); let n = self.channels.len(); @@ -2202,23 +2204,23 @@ let request = Request::This(1, 2); assert!(rq.request(request).is_ok()); let request = rp.take_request().unwrap(); - println!("rp got request: {request:?}"); + println!("rp got request: {request:?}"); let response = Response::There(-1); assert!(!rp.is_canceled()); assert!(rp.respond(response).is_ok()); let response = rq.take_response().unwrap(); - println!("rq got response: {response:?}"); + println!("rq got response: {response:?}"); // early cancelation path assert!(rq.request(request).is_ok()); let request = rq.cancel().unwrap().unwrap(); - println!("responder could cancel: {request:?}"); + println!("responder could cancel: {request:?}"); assert!(rp.take_request().is_none()); assert_eq!(State::Idle, rq.state()); // late cancelation assert!(rq.request(request).is_ok()); let request = rp.take_request().unwrap(); println!( - "responder could cancel: {:?}", + "responder could cancel: {:?}", &rq.cancel().unwrap().is_none() ); assert_eq!(request, Request::This(1, 2)); @@ -2231,7 +2233,7 @@ assert!(rq.send_request().is_ok()); let request = rp.take_request().unwrap(); assert_eq!(request, Request::This(1, 2)); - println!("rp got request: {request:?}"); + println!("rp got request: {request:?}"); // building into response buffer rp.with_response_mut(|r| *r = Response::Here(3, 2, 1)) .unwrap(); @@ -2243,7 +2245,7 @@ #[test] fn interchange_ref() { static INTERCHANGE_INNER: Interchange<Request, Response, 1> = Interchange::new(); - static INTERCHANGE: InterchangeRef<'static, Request, Response> = + static INTERCHANGE: InterchangeRef<'static, Request, Response> = INTERCHANGE_INNER.as_interchange_ref(); let (mut rq, mut rp) = INTERCHANGE.claim().unwrap(); assert_eq!(rq.state(), State::Idle); @@ -2251,23 +2253,23 @@ let request = Request::This(1, 2); assert!(rq.request(request).is_ok()); let request = rp.take_request().unwrap(); - println!("rp got request: {request:?}"); + println!("rp got request: {request:?}"); let response = Response::There(-1); assert!(!rp.is_canceled()); assert!(rp.respond(response).is_ok()); let response = rq.take_response().unwrap(); - println!("rq got response: {response:?}"); + println!("rq got response: {response:?}"); // early cancelation path assert!(rq.request(request).is_ok()); let request = rq.cancel().unwrap().unwrap(); - println!("responder could cancel: {request:?}"); + println!("responder could cancel: {request:?}"); assert!(rp.take_request().is_none()); assert_eq!(State::Idle, rq.state()); // late cancelation assert!(rq.request(request).is_ok()); let request = rp.take_request().unwrap(); println!( - "responder could cancel: {:?}", + "responder could cancel: {:?}", &rq.cancel().unwrap().is_none() ); assert_eq!(request, Request::This(1, 2)); @@ -2280,7 +2282,7 @@ assert!(rq.send_request().is_ok()); let request = rp.take_request().unwrap(); assert_eq!(request, Request::This(1, 2)); - println!("rp got request: {request:?}"); + println!("rp got request: {request:?}"); // building into response buffer rp.with_response_mut(|r| *r = Response::Here(3, 2, 1)) .unwrap(); @@ -2292,22 +2294,22 @@ #[allow(unconditional_recursion, clippy::extra_unused_type_parameters, unused)] fn assert_send<T: Send>() { assert_send::<Channel<String, u32>>(); - assert_send::<Responder<'static, String, u32>>(); - assert_send::<Requester<'static, String, u32>>(); - assert_send::<Channel<&'static mut String, u32>>(); - assert_send::<Responder<'static, &'static mut String, u32>>(); - assert_send::<Requester<'static, &'static mut String, u32>>(); + assert_send::<Responder<'static, String, u32>>(); + assert_send::<Requester<'static, String, u32>>(); + assert_send::<Channel<&'static mut String, u32>>(); + assert_send::<Responder<'static, &'static mut String, u32>>(); + assert_send::<Requester<'static, &'static mut String, u32>>(); } #[allow(unconditional_recursion, clippy::extra_unused_type_parameters, unused)] fn assert_sync<T: Sync>() { assert_sync::<Channel<String, u32>>(); assert_sync::<Channel<String, u32>>(); - assert_sync::<Responder<'static, String, u32>>(); - assert_sync::<Requester<'static, String, u32>>(); + assert_sync::<Responder<'static, String, u32>>(); + assert_sync::<Requester<'static, String, u32>>(); - assert_sync::<Channel<&'static mut String, u32>>(); - assert_sync::<Responder<'static, &'static mut String, u32>>(); - assert_sync::<Requester<'static, &'static mut String, u32>>(); + assert_sync::<Channel<&'static mut String, u32>>(); + assert_sync::<Responder<'static, &'static mut String, u32>>(); + assert_sync::<Requester<'static, &'static mut String, u32>>(); } }
"+searchState.loadingText+"
";searchState.showResults(search)},descShards:new Map(),loadDesc:async function({descShard,descIndex}){if(descShard.promise===null){descShard.promise=new Promise((resolve,reject)=>{descShard.resolve=resolve;const ds=descShard;const fname=`${ds.crate}-desc-${ds.shard}-`;const url=resourcePath(`search.desc/${descShard.crate}/${fname}`,".js",);loadScript(url,reject)})}const list=await descShard.promise;return list[descIndex]},loadedDescShard:function(crate,shard,data){this.descShards.get(crate)[shard].resolve(data.split("\n"))},};const toggleAllDocsId="toggle-all-docs";let savedHash="";function handleHashes(ev){if(ev!==null&&searchState.isDisplayed()&&ev.newURL){switchDisplayedElement(null);const hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.search+"#"+hash)}const elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}const pageId=window.location.hash.replace(/^#/,"");if(savedHash!==pageId){savedHash=pageId;if(pageId!==""){expandSection(pageId)}}if(savedHash.startsWith("impl-")){const splitAt=savedHash.indexOf("/");if(splitAt!==-1){const implId=savedHash.slice(0,splitAt);const assocId=savedHash.slice(splitAt+1);const implElem=document.getElementById(implId);if(implElem&&implElem.parentElement.tagName==="SUMMARY"&&implElem.parentElement.parentElement.tagName==="DETAILS"){onEachLazy(implElem.parentElement.parentElement.querySelectorAll(`[id^="${assocId}"]`),item=>{const numbered=/([^-]+)-([0-9]+)/.exec(item.id);if(item.id===assocId||(numbered&&numbered[1]===assocId)){openParentDetails(item);item.scrollIntoView();setTimeout(()=>{window.location.replace("#"+item.id)},0)}},)}}}}function onHashChange(ev){hideSidebar();handleHashes(ev)}function openParentDetails(elem){while(elem){if(elem.tagName==="DETAILS"){elem.open=true}elem=elem.parentNode}}function expandSection(id){openParentDetails(document.getElementById(id))}function handleEscape(ev){searchState.clearInputTimeout();searchState.hideResults();ev.preventDefault();searchState.defocus();window.hideAllModals(true)}function handleShortcut(ev){const disableShortcuts=getSettingValue("disable-shortcuts")==="true";if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts){return}if(document.activeElement.tagName==="INPUT"&&document.activeElement.type!=="checkbox"&&document.activeElement.type!=="radio"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":case"/":ev.preventDefault();searchState.focus();break;case"+":ev.preventDefault();expandAllDocs();break;case"-":ev.preventDefault();collapseAllDocs();break;case"?":showHelp();break;default:break}}}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);function addSidebarItems(){if(!window.SIDEBAR_ITEMS){return}const sidebar=document.getElementsByClassName("sidebar-elems")[0];function block(shortty,id,longty){const filtered=window.SIDEBAR_ITEMS[shortty];if(!filtered){return}const modpath=hasClass(document.querySelector(".rustdoc"),"mod")?"../":"";const h3=document.createElement("h3");h3.innerHTML=`${longty}`;const ul=document.createElement("ul");ul.className="block "+shortty;for(const name of filtered){let path;if(shortty==="mod"){path=`${modpath}${name}/index.html`}else{path=`${modpath}${shortty}.${name}.html`}let current_page=document.location.href.toString();if(current_page.endsWith("/")){current_page+="index.html"}const link=document.createElement("a");link.href=path;if(path===current_page){link.className="current"}link.textContent=name;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebar.appendChild(h3);sidebar.appendChild(ul)}if(sidebar){block("primitive","primitives","Primitive Types");block("mod","modules","Modules");block("macro","macros","Macros");block("struct","structs","Structs");block("enum","enums","Enums");block("constant","constants","Constants");block("static","static","Statics");block("trait","traits","Traits");block("fn","functions","Functions");block("type","types","Type Aliases");block("union","unions","Unions");block("foreigntype","foreign-types","Foreign Types");block("keyword","keywords","Keywords");block("opaque","opaque-types","Opaque Types");block("attr","attributes","Attribute Macros");block("derive","derives","Derive Macros");block("traitalias","trait-aliases","Trait Aliases")}}window.register_implementors=imp=>{const implementors=document.getElementById("implementors-list");const synthetic_implementors=document.getElementById("synthetic-implementors-list");const inlined_types=new Set();const TEXT_IDX=0;const SYNTHETIC_IDX=1;const TYPES_IDX=2;if(synthetic_implementors){onEachLazy(synthetic_implementors.getElementsByClassName("impl"),el=>{const aliases=el.getAttribute("data-aliases");if(!aliases){return}aliases.split(",").forEach(alias=>{inlined_types.add(alias)})})}let currentNbImpls=implementors.getElementsByClassName("impl").length;const traitName=document.querySelector(".main-heading h1 > .trait").textContent;const baseIdName="impl-"+traitName+"-";const libs=Object.getOwnPropertyNames(imp);const script=document.querySelector("script[data-ignore-extern-crates]");const ignoreExternCrates=new Set((script?script.getAttribute("data-ignore-extern-crates"):"").split(","),);for(const lib of libs){if(lib===window.currentCrate||ignoreExternCrates.has(lib)){continue}const structs=imp[lib];struct_loop:for(const struct of structs){const list=struct[SYNTHETIC_IDX]?synthetic_implementors:implementors;if(struct[SYNTHETIC_IDX]){for(const struct_type of struct[TYPES_IDX]){if(inlined_types.has(struct_type)){continue struct_loop}inlined_types.add(struct_type)}}const code=document.createElement("h3");code.innerHTML=struct[TEXT_IDX];addClass(code,"code-header");onEachLazy(code.getElementsByTagName("a"),elem=>{const href=elem.getAttribute("href");if(href&&!href.startsWith("#")&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});const currentId=baseIdName+currentNbImpls;const anchor=document.createElement("a");anchor.href="#"+currentId;addClass(anchor,"anchor");const display=document.createElement("div");display.id=currentId;addClass(display,"impl");display.appendChild(anchor);display.appendChild(code);list.appendChild(display);currentNbImpls+=1}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors)}window.register_type_impls=imp=>{if(!imp||!imp[window.currentCrate]){return}window.pending_type_impls=null;const idMap=new Map();let implementations=document.getElementById("implementations-list");let trait_implementations=document.getElementById("trait-implementations-list");let trait_implementations_header=document.getElementById("trait-implementations");const script=document.querySelector("script[data-self-path]");const selfPath=script?script.getAttribute("data-self-path"):null;const mainContent=document.querySelector("#main-content");const sidebarSection=document.querySelector(".sidebar section");let methods=document.querySelector(".sidebar .block.method");let associatedTypes=document.querySelector(".sidebar .block.associatedtype");let associatedConstants=document.querySelector(".sidebar .block.associatedconstant");let sidebarTraitList=document.querySelector(".sidebar .block.trait-implementation");for(const impList of imp[window.currentCrate]){const types=impList.slice(2);const text=impList[0];const isTrait=impList[1]!==0;const traitName=impList[1];if(types.indexOf(selfPath)===-1){continue}let outputList=isTrait?trait_implementations:implementations;if(outputList===null){const outputListName=isTrait?"Trait Implementations":"Implementations";const outputListId=isTrait?"trait-implementations-list":"implementations-list";const outputListHeaderId=isTrait?"trait-implementations":"implementations";const outputListHeader=document.createElement("h2");outputListHeader.id=outputListHeaderId;outputListHeader.innerText=outputListName;outputList=document.createElement("div");outputList.id=outputListId;if(isTrait){const link=document.createElement("a");link.href=`#${outputListHeaderId}`;link.innerText="Trait Implementations";const h=document.createElement("h3");h.appendChild(link);trait_implementations=outputList;trait_implementations_header=outputListHeader;sidebarSection.appendChild(h);sidebarTraitList=document.createElement("ul");sidebarTraitList.className="block trait-implementation";sidebarSection.appendChild(sidebarTraitList);mainContent.appendChild(outputListHeader);mainContent.appendChild(outputList)}else{implementations=outputList;if(trait_implementations){mainContent.insertBefore(outputListHeader,trait_implementations_header);mainContent.insertBefore(outputList,trait_implementations_header)}else{const mainContent=document.querySelector("#main-content");mainContent.appendChild(outputListHeader);mainContent.appendChild(outputList)}}}const template=document.createElement("template");template.innerHTML=text;onEachLazy(template.content.querySelectorAll("a"),elem=>{const href=elem.getAttribute("href");if(href&&!href.startsWith("#")&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});onEachLazy(template.content.querySelectorAll("[id]"),el=>{let i=0;if(idMap.has(el.id)){i=idMap.get(el.id)}else if(document.getElementById(el.id)){i=1;while(document.getElementById(`${el.id}-${2 * i}`)){i=2*i}while(document.getElementById(`${el.id}-${i}`)){i+=1}}if(i!==0){const oldHref=`#${el.id}`;const newHref=`#${el.id}-${i}`;el.id=`${el.id}-${i}`;onEachLazy(template.content.querySelectorAll("a[href]"),link=>{if(link.getAttribute("href")===oldHref){link.href=newHref}})}idMap.set(el.id,i+1)});const templateAssocItems=template.content.querySelectorAll("section.tymethod, "+"section.method, section.associatedtype, section.associatedconstant");if(isTrait){const li=document.createElement("li");const a=document.createElement("a");a.href=`#${template.content.querySelector(".impl").id}`;a.textContent=traitName;li.appendChild(a);sidebarTraitList.append(li)}else{onEachLazy(templateAssocItems,item=>{let block=hasClass(item,"associatedtype")?associatedTypes:(hasClass(item,"associatedconstant")?associatedConstants:(methods));if(!block){const blockTitle=hasClass(item,"associatedtype")?"Associated Types":(hasClass(item,"associatedconstant")?"Associated Constants":("Methods"));const blockClass=hasClass(item,"associatedtype")?"associatedtype":(hasClass(item,"associatedconstant")?"associatedconstant":("method"));const blockHeader=document.createElement("h3");const blockLink=document.createElement("a");blockLink.href="#implementations";blockLink.innerText=blockTitle;blockHeader.appendChild(blockLink);block=document.createElement("ul");block.className=`block ${blockClass}`;const insertionReference=methods||sidebarTraitList;if(insertionReference){const insertionReferenceH=insertionReference.previousElementSibling;sidebarSection.insertBefore(blockHeader,insertionReferenceH);sidebarSection.insertBefore(block,insertionReferenceH)}else{sidebarSection.appendChild(blockHeader);sidebarSection.appendChild(block)}if(hasClass(item,"associatedtype")){associatedTypes=block}else if(hasClass(item,"associatedconstant")){associatedConstants=block}else{methods=block}}const li=document.createElement("li");const a=document.createElement("a");a.innerText=item.id.split("-")[0].split(".")[1];a.href=`#${item.id}`;li.appendChild(a);block.appendChild(li)})}outputList.appendChild(template.content)}for(const list of[methods,associatedTypes,associatedConstants,sidebarTraitList]){if(!list){continue}const newChildren=Array.prototype.slice.call(list.children);newChildren.sort((a,b)=>{const aI=a.innerText;const bI=b.innerText;return aIbI?1:0});list.replaceChildren(...newChildren)}};if(window.pending_type_impls){window.register_type_impls(window.pending_type_impls)}function addSidebarCrates(){if(!window.ALL_CRATES){return}const sidebarElems=document.getElementsByClassName("sidebar-elems")[0];if(!sidebarElems){return}const h3=document.createElement("h3");h3.innerHTML="Crates";const ul=document.createElement("ul");ul.className="block crate";for(const crate of window.ALL_CRATES){const link=document.createElement("a");link.href=window.rootPath+crate+"/index.html";link.textContent=crate;const li=document.createElement("li");if(window.rootPath!=="./"&&crate===window.currentCrate){li.className="current"}li.appendChild(link);ul.appendChild(li)}sidebarElems.appendChild(h3);sidebarElems.appendChild(ul)}function expandAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);removeClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hasClass(e,"type-contents-toggle")&&!hasClass(e,"more-examples-toggle")){e.open=true}});innerToggle.title="collapse all docs";innerToggle.children[0].innerText="\u2212"}function collapseAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);addClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(e.parentNode.id!=="implementations-list"||(!hasClass(e,"implementors-toggle")&&!hasClass(e,"type-contents-toggle"))){e.open=false}});innerToggle.title="expand all docs";innerToggle.children[0].innerText="+"}function toggleAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);if(!innerToggle){return}if(hasClass(innerToggle,"will-expand")){expandAllDocs()}else{collapseAllDocs()}}(function(){const toggles=document.getElementById(toggleAllDocsId);if(toggles){toggles.onclick=toggleAllDocs}const hideMethodDocs=getSettingValue("auto-hide-method-docs")==="true";const hideImplementations=getSettingValue("auto-hide-trait-implementations")==="true";const hideLargeItemContents=getSettingValue("auto-hide-large-items")!=="false";function setImplementorsTogglesOpen(id,open){const list=document.getElementById(id);if(list!==null){onEachLazy(list.getElementsByClassName("implementors-toggle"),e=>{e.open=open})}}if(hideImplementations){setImplementorsTogglesOpen("trait-implementations-list",false);setImplementorsTogglesOpen("blanket-implementations-list",false)}onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hideLargeItemContents&&hasClass(e,"type-contents-toggle")){e.open=true}if(hideMethodDocs&&hasClass(e,"method-toggle")){e.open=false}})}());window.rustdoc_add_line_numbers_to_examples=()=>{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");if(line_numbers.length>0){return}const count=x.textContent.split("\n").length;const elems=[];for(let i=0;i {onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");for(const node of line_numbers){parent.removeChild(node)}})};if(getSettingValue("line-numbers")==="true"){window.rustdoc_add_line_numbers_to_examples()}function showSidebar(){window.hideAllModals(false);const sidebar=document.getElementsByClassName("sidebar")[0];addClass(sidebar,"shown")}function hideSidebar(){const sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"shown")}window.addEventListener("resize",()=>{if(window.CURRENT_TOOLTIP_ELEMENT){const base=window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE;const force_visible=base.TOOLTIP_FORCE_VISIBLE;hideTooltip(false);if(force_visible){showTooltip(base);base.TOOLTIP_FORCE_VISIBLE=true}}});const mainElem=document.getElementById(MAIN_ID);if(mainElem){mainElem.addEventListener("click",hideSidebar)}onEachLazy(document.querySelectorAll("a[href^='#']"),el=>{el.addEventListener("click",()=>{expandSection(el.hash.slice(1));hideSidebar()})});onEachLazy(document.querySelectorAll(".toggle > summary:not(.hideme)"),el=>{el.addEventListener("click",e=>{if(e.target.tagName!=="SUMMARY"&&e.target.tagName!=="A"){e.preventDefault()}})});function showTooltip(e){const notable_ty=e.getAttribute("data-notable-ty");if(!window.NOTABLE_TRAITS&¬able_ty){const data=document.getElementById("notable-traits-data");if(data){window.NOTABLE_TRAITS=JSON.parse(data.innerText)}else{throw new Error("showTooltip() called with notable without any notable traits!")}}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE===e){clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);return}window.hideAllModals(false);const wrapper=document.createElement("div");if(notable_ty){wrapper.innerHTML=" "+window.NOTABLE_TRAITS[notable_ty]+""}else{if(e.getAttribute("title")!==null){e.setAttribute("data-title",e.getAttribute("title"));e.removeAttribute("title")}if(e.getAttribute("data-title")!==null){const titleContent=document.createElement("div");titleContent.className="content";titleContent.appendChild(document.createTextNode(e.getAttribute("data-title")));wrapper.appendChild(titleContent)}}wrapper.className="tooltip popover";const focusCatcher=document.createElement("div");focusCatcher.setAttribute("tabindex","0");focusCatcher.onfocus=hideTooltip;wrapper.appendChild(focusCatcher);const pos=e.getBoundingClientRect();wrapper.style.top=(pos.top+window.scrollY+pos.height)+"px";wrapper.style.left=0;wrapper.style.right="auto";wrapper.style.visibility="hidden";const body=document.getElementsByTagName("body")[0];body.appendChild(wrapper);const wrapperPos=wrapper.getBoundingClientRect();const finalPos=pos.left+window.scrollX-wrapperPos.width+24;if(finalPos>0){wrapper.style.left=finalPos+"px"}else{wrapper.style.setProperty("--popover-arrow-offset",(wrapperPos.right-pos.right+4)+"px",)}wrapper.style.visibility="";window.CURRENT_TOOLTIP_ELEMENT=wrapper;window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE=e;clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);wrapper.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}clearTooltipHoverTimeout(e)};wrapper.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&!e.contains(ev.relatedTarget)){setTooltipHoverTimeout(e,false);addClass(wrapper,"fade-out")}}}function setTooltipHoverTimeout(element,show){clearTooltipHoverTimeout(element);if(!show&&!window.CURRENT_TOOLTIP_ELEMENT){return}if(show&&window.CURRENT_TOOLTIP_ELEMENT){return}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE!==element){return}element.TOOLTIP_HOVER_TIMEOUT=setTimeout(()=>{if(show){showTooltip(element)}else if(!element.TOOLTIP_FORCE_VISIBLE){hideTooltip(false)}},show?window.RUSTDOC_TOOLTIP_HOVER_MS:window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS)}function clearTooltipHoverTimeout(element){if(element.TOOLTIP_HOVER_TIMEOUT!==undefined){removeClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out");clearTimeout(element.TOOLTIP_HOVER_TIMEOUT);delete element.TOOLTIP_HOVER_TIMEOUT}}function tooltipBlurHandler(event){if(window.CURRENT_TOOLTIP_ELEMENT&&!window.CURRENT_TOOLTIP_ELEMENT.contains(document.activeElement)&&!window.CURRENT_TOOLTIP_ELEMENT.contains(event.relatedTarget)&&!window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.contains(document.activeElement)&&!window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.contains(event.relatedTarget)){setTimeout(()=>hideTooltip(false),0)}}function hideTooltip(focus){if(window.CURRENT_TOOLTIP_ELEMENT){if(window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE){if(focus){window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.focus()}window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE=false}const body=document.getElementsByTagName("body")[0];body.removeChild(window.CURRENT_TOOLTIP_ELEMENT);clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);window.CURRENT_TOOLTIP_ELEMENT=null}}onEachLazy(document.getElementsByClassName("tooltip"),e=>{e.onclick=()=>{e.TOOLTIP_FORCE_VISIBLE=e.TOOLTIP_FORCE_VISIBLE?false:true;if(window.CURRENT_TOOLTIP_ELEMENT&&!e.TOOLTIP_FORCE_VISIBLE){hideTooltip(true)}else{showTooltip(e);window.CURRENT_TOOLTIP_ELEMENT.setAttribute("tabindex","0");window.CURRENT_TOOLTIP_ELEMENT.focus();window.CURRENT_TOOLTIP_ELEMENT.onblur=tooltipBlurHandler}return false};e.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointermove=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&window.CURRENT_TOOLTIP_ELEMENT&&!window.CURRENT_TOOLTIP_ELEMENT.contains(ev.relatedTarget)){setTooltipHoverTimeout(e,false);addClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out")}}});const sidebar_menu_toggle=document.getElementsByClassName("sidebar-menu-toggle")[0];if(sidebar_menu_toggle){sidebar_menu_toggle.addEventListener("click",()=>{const sidebar=document.getElementsByClassName("sidebar")[0];if(!hasClass(sidebar,"shown")){showSidebar()}else{hideSidebar()}})}function helpBlurHandler(event){blurHandler(event,getHelpButton(),window.hidePopoverMenus)}function buildHelpMenu(){const book_info=document.createElement("span");const channel=getVar("channel");book_info.className="top";book_info.innerHTML=`You can find more information in \ +the rustdoc book.`;const shortcuts=[["?","Show this help dialog"],["S / /","Focus the search field"],["↑","Move up in search results"],["↓","Move down in search results"],["← / →","Switch result tab (when results focused)"],["⏎","Go to active search result"],["+","Expand all sections"],["-","Collapse all sections"],].map(x=>""+x[0].split(" ").map((y,index)=>((index&1)===0?""+y+"":" "+y+" ")).join("")+" "+x[1]+" ").join("");const div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="Keyboard Shortcuts
"+shortcuts+"
fn:
) to \
+ restrict the search to a given item kind.","Accepted kinds are: fn
, mod
, struct
, \
+ enum
, trait
, type
, macro
, \
+ and const
.","Search functions by type signature (e.g., vec -> usize
or \
+ -> vec
or String, enum:Cow -> bool
)","You can look for items with an exact name by putting double quotes around \
+ your request: \"string\"
","Look for functions that accept or return \
+ slices and \
+ arrays by writing \
+ square brackets (e.g., -> [u8]
or [] -> Option
)","Look for items inside another one by searching for a path: vec::Vec
",].map(x=>""+x+"
").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="fn:
) to \
- restrict the search to a given item kind.","Accepted kinds are: fn
, mod
, struct
, \
- enum
, trait
, type
, macro
, \
- and const
.","Search functions by type signature (e.g., vec -> usize
or \
- -> vec
or String, enum:Cow -> bool
)","You can look for items with an exact name by putting double quotes around \
- your request: \"string\"
","Look for items inside another one by searching for a path: vec::Vec
",].map(x=>""+x+"
").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="${value.replaceAll(" ", " ")}
`}else{error[index]=value}});output+=`${value}
`}else{error[index]=value}});output+=`