pub struct MessageEndpoint(/* private fields */);Expand description
The endpoint event’s data, parsed once and used verbatim.
A newtype over the whole target rather than a decomposed
(path, query, session). Decomposing is the mistake: it makes the client’s
next move “rebuild the URL”, and rebuilding is where a server’s choice of
encoding becomes this client’s bug.
Implementations§
Source§impl MessageEndpoint
impl MessageEndpoint
Sourcepub fn path(&self) -> &str
pub fn path(&self) -> &str
The target’s path, without any query.
For a server logging what it offered, and for a test asserting the
shape. A client has no use for this: it POSTs to
as_str.
Sourcepub fn bare_path(value: &str) -> Result<Self, MessageEndpointError>
pub fn bare_path(value: &str) -> Result<Self, MessageEndpointError>
A path with no query and no fragment, for a server that will append one.
Distinct from FromStr because a configured path and an advertised
endpoint are different shapes, and only one of them may carry a query.
A path of /messages?tenant=a parses fine as a target — a client could
be told to post there — but a server that then appends sessionId to it
produces /messages?tenant=a?sessionId=1, whose second ? is data
rather than a delimiter, and a client that splits on it gets a query of
a?sessionId=1 and posts with no session at all. A # is worse: it
makes the whole query a fragment, which the client drops silently.
Refusing both here is what lets with_query_parameter
be infallible.
§Errors
MessageEndpointError::NotAbsolutePath for an empty value, a
non-/-initial one, one that is a query string, or one that names a
scheme; MessageEndpointError::IllegalCharacter for a C0 control,
DEL, or a space; and MessageEndpointError::QueryOrFragment for a
value that already carries a ? or a #.
Sourcepub fn with_query_parameter(&self, key: &str, value: &str) -> Self
pub fn with_query_parameter(&self, key: &str, value: &str) -> Self
This target with one more query parameter appended.
Infallible, and that is the whole point: the result is a string this
module assembled from a bare_path it already
validated and a key and value it is choosing, so there is nothing left
to parse and no way for the result to be one FromStr would refuse.
An existing query is preserved rather than replaced — ?tenant=a plus
sessionId=1 is ?tenant=a&sessionId=1 — because the alternative is a
server that silently discards its own configuration the first time a
client is added.
key and value are not validated here, and cannot be: the only
callers in this crate pass a &'static str constant and a hexadecimal
session id. A caller with an arbitrary string should parse it into a
MessageEndpoint instead of reaching for this.
Trait Implementations§
Source§impl Clone for MessageEndpoint
impl Clone for MessageEndpoint
Source§impl Debug for MessageEndpoint
impl Debug for MessageEndpoint
Source§impl Display for MessageEndpoint
impl Display for MessageEndpoint
impl Eq for MessageEndpoint
Source§impl FromStr for MessageEndpoint
impl FromStr for MessageEndpoint
Source§fn from_str(value: &str) -> Result<Self, Self::Err>
fn from_str(value: &str) -> Result<Self, Self::Err>
Parses a target the client can safely resolve against the origin it already dialled.
§Errors
MessageEndpointError::Emptyfor an empty target or a bare?.MessageEndpointError::ProtocolRelativefor a//prefix, which carries no scheme and so escapes a check that only looks for one.MessageEndpointError::Absolutefor anything with a scheme. The check is on the scheme syntax, not on the literal://, somailto:xanddata:text/plain,xare caught as well ashttps://host/.MessageEndpointError::IllegalCharacterfor a C0 control, DEL, or a space.MessageEndpointError::NotAbsolutePathfor a target that is neither empty nor/-initial: a relativemessages?sessionId=xis ambiguous against whatever the client’s current path happens to be, and resolving it the way a browser would is not a behaviour a protocol should depend on.