diff --git a/help.html b/help.html index 84a65ca4..bab2a5b7 100644 --- a/help.html +++ b/help.html @@ -1,2 +1,2 @@ -
std::path::Path
into an URL in …","Convert a file name as std::path::Path
into an URL in the …","","","Get the path to api.toml
","","Return whether the URL has an ‘authority’, which can …","Equivalent to url.host().is_some()
.","","","","","","","Return a JSON expression with status 200 indicating the …","Return the parsed representation of the host for this URL. …","Return the string representation of the host (domain or IP …","","","","","","","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","","","","","Return the serialization of this URL.","","Return whether the URL is special (has a special scheme)","Parse a string as an URL, with this URL as the base URL.","Load the web API or panic","Creates a relative URL if possible, with this URL as the …","Interfaces for methods of accessing to state.","Support for routes using the Prometheus metrics format.","","Return a default ParseOptions
that can fully configure the …","","Return the origin of this URL (…","Parse an absolute URL from a string.","Parse an absolute URL from a string and add params to its …","","Return the password for this URL, if any, as a …","Return the path for this URL, as a percent-encoded ASCII …","Unless this URL is cannot-be-a-base, return an iterator of …","Return an object with methods to manipulate this URL’s …","Return the port number for this URL, if any.","Return the port number for this URL, or the default port …","Return this URL’s query string, if any, as a …","Parse the URL’s query string, if any, as …","Manipulate this URL’s query string, viewed as a sequence …","","","","Return the scheme of this URL, lower-cased, as an ASCII …","","Serialize with Serde using the internal representation of …","Change this URL’s fragment identifier.","Change this URL’s host.","Change this URL’s host to the given IP address.","Change this URL’s password.","Change this URL’s path.","Change this URL’s port number.","Change this URL’s query string.","Change this URL’s scheme.","Change this URL’s username.","An interface for asynchronous communication with clients, …","Resolve a URL’s host and port number to SocketAddr
.","","","Assuming the URL is in the file
scheme or similar, convert …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Return the username for this URL (typically the empty …","","","","","","","Wait for the server to respond to a connection request","","A description of an API.","An error encountered when parsing or constructing an Api.","Metadata used for describing and documenting an API.","","Version information about an API.","","","","","","","","","","","The version of this API.","","Register a handler for a route.","","","","","","","","","","","","","","","","","","Register a handler for a DELETE route.","","A description of this API.","","","","","","","","","","","","","","","","","","The version of the Tide Disco API specification format.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Create an Api by reading a TOML specification from a file.","Register a handler for a GET route.","","The heading preceding documentation of a route description.","The heading for documentation of a route.","The heading preceding documentation of route parameters.","The heading preceding documentation of all routes in this …","HTML to be appended to automatically generated …","HTML to be prepended to automatically generated …","","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Register a handler for a METRICS route.","The name of this API.","Parse an API from a TOML specification.","Documentation to insert in the parameters section of a …","HTML formatting an entry in a table documenting the …","HTML closing a table documenting the parameters of a route.","HTML preceding the contents of a table documenting the …","Register a handler for a POST route.","Register a handler for a PUT route.","HTML formatting the path of a route.","","","Register a handler for a SOCKET route.","","The format version of the TOML specification used to load …","Register a uni-directional handler for a SOCKET route.","","","","","","","","","","","","","","","","","","","","","Set the health check handler for this API.","Serve the contents of dir
at the URL /public/{{NAME}}
.","Set the API version.","","","","","","","","","A tide-disco server application.","An error encountered while building an App.","The health status of an application.","Version information about an application.","The Listener trait represents an implementation of http …","What listener are we converting into?","RAII guard to ensure a module is registered after it is …","","ToListener represents any type that can be converted into a","Start accepting incoming connections. This method must be …","The version of this application.","","","Bind the listener. This starts the listening process by …","","","","","","","","","","","","","","","","","","","","","","","The version of the Tide Disco server framework.","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Check the health of each registered module in response to …","","Expose information about the connection. This should …","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Create and register an API module.","Check the health of the named module.","The status of each registered module, indexed by version.","The supported versions of each module registered with this …","Register this module with the linked app.","Register an API module.","","","Serve the App asynchronously.","","","The status of the overall application.","Transform self into a Listener
. Unless self is already …","","","","","","","","","","","","","","","","","","","","Get the version of this application.","","","","","","Create a new App with a given state.","Set the application version.","","Errors which can be serialized in a response body.","The simplest possible implementation of Error.","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","","","","","","","","","","","","Calls U::from(self)
.","","","","","","","","","","","","","","","A response to a healthcheck endpoint.","Common health statuses of an application.","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Calls U::from(self)
.","","The status of this health check.","","","","","","","","","","","A state which allows read access.","","The type of state which this type allows a caller to read.","A state which allows exclusive, write access.","","","","","","","The HTTP DELETE method.","","","","","","","","Returns the argument unchanged.","","Returns the argument unchanged.","","The HTTP GET method.","","Calls U::from(self)
.","Calls U::from(self)
.","Check if a method is a standard HTTP method.","Check if a request method implies mutable access to the …","The Tide Disco METRICS method.","The HTTP POST method.","The HTTP PUT method.","Do an operation with immutable access to the state.","The Tide Disco SOCKET method.","","","","","","","","","","","Do an operation with mutable access to the state.","","","","","","","","","","","","","","","","","","","","","","","Parameters passed to a route handler.","","","","","","The Accept header of this request.","","","","","","","","Get the value of a named parameter and convert it to a …","Deserialize the body of a request.","","","Get the value of a named parameter and convert it to a bool…","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","The headers of the incoming request.","","Get the value of a named parameter and convert it to an …","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","The Method used to dispatch the request.","","Parse a parameter from a Request.","Get the value of a named optional parameter and convert it …","Get the value of a named optional parameter and convert it …","Get the value of a named optional parameter and convert it …","Get the value of a named optional parameter.","Get the value of a named optional parameter and convert it …","Get the value of a named optional parameter and convert it …","Get the value of a named parameter.","","","","Get the remote address for this request.","","","","Get the value of a named parameter and convert it to a …","Get the value of a named parameter and convert it to …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","A connection facilitating bi-directional, asynchronous …","","","","An error returned by a socket handler.","","","","","","","","","","","Returns the argument unchanged.","","","","Returns the argument unchanged.","","","Calls U::from(self)
.","Calls U::from(self)
.","","","","","","","","","","","","","","","","","","","","","202 Accepted","502 Bad Gateway","400 Bad Request","409 Conflict","100 Continue","201 Created","103 Early Hints","417 Expectation Failed","424 Failed Dependency","403 Forbidden","302 Found","504 Gateway Timeout","410 Gone","505 HTTP Version Not Supported","418 I’m a teapot","226 Im Used","507 Insufficient Storage","500 Internal Server Error","411 Length Required","423 Locked","508 Loop Detected","405 Method Not Allowed","421 Misdirected Request","301 Moved Permanently","207 Multi-Status","300 Multiple Choice","511 Network Authentication Required","204 No Content","203 Non Authoritative Information","406 Not Acceptable","510 Not Extended","404 Not Found","501 Not Implemented","304 Not Modified","200 Ok","","206 Partial Content","413 Payload Too Large","402 Payment Required","308 Permanent Redirect","412 Precondition Failed","428 Precondition Required","407 Proxy Authentication Required","431 Request Header Fields Too Large","408 Request Timeout","416 Requested Range Not Satisfiable","205 Reset Content","303 See Other","503 Service Unavailable","Serializable HTTP status code.","101 Switching Protocols","307 Temporary Redirect","425 Too Early","429 Too Many Requests","401 Unauthorized","451 Unavailable For Legal Reasons","422 Unprocessable Entity","415 Unsupported Media Type","426 Upgrade Required","414 URI Too Long","506 Variant Also Negotiates","","","","","","","The canonical reason for a given status code","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","Calls U::from(self)
.","Calls U::from(self)
.","Returns true
if the status code is the 4xx
range.","Returns true
if the status code is 1xx
range.","Returns true
if the status code is the 3xx
range.","Returns true
if the status code is the 5xx
range.","Returns true
if the status code is the 2xx
range.","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","","Calls U::from(self)
.","","","","","","","","","",""],"i":[0,0,0,0,145,5,145,11,145,0,0,0,145,0,11,0,145,11,11,0,0,0,0,0,0,0,0,0,5,0,5,145,145,11,0,0,26,4,0,26,4,0,0,39,9,4,3,4,5,3,26,26,3,26,4,3,26,4,5,9,11,3,26,4,5,9,11,3,0,3,5,9,11,3,5,9,11,3,3,0,0,0,3,5,3,4,3,3,3,3,3,3,0,3,3,26,4,5,5,11,3,3,26,4,5,9,11,26,26,3,3,3,11,0,26,3,3,3,3,5,39,9,0,0,3,3,0,3,3,3,3,0,3,26,4,5,9,11,3,3,3,3,3,3,11,3,3,0,3,0,0,11,3,0,3,3,3,3,3,3,3,3,3,3,3,3,3,0,39,9,3,3,3,3,3,3,3,3,3,3,3,3,0,3,0,0,3,3,3,5,9,11,3,5,3,3,26,4,5,9,11,11,3,26,4,5,9,11,3,26,4,5,9,11,26,26,3,3,26,4,5,9,11,0,76,0,0,0,76,0,76,76,76,76,76,76,76,76,76,76,82,76,75,76,76,82,83,75,76,82,83,75,76,76,82,83,76,82,83,83,75,76,83,82,83,76,82,76,76,76,76,82,82,82,82,76,76,82,83,75,83,76,82,83,75,75,75,76,83,83,83,83,83,83,76,76,82,83,75,75,83,75,83,83,83,83,75,75,83,82,83,75,76,82,75,76,82,83,76,76,82,83,75,76,82,83,75,76,82,83,75,76,82,83,75,75,75,75,146,146,147,148,148,149,150,99,0,0,0,0,0,110,0,99,0,95,102,99,99,95,103,106,99,101,102,103,106,99,101,102,99,99,101,102,99,101,102,103,103,99,101,102,102,103,99,101,102,99,99,99,99,101,101,101,101,102,102,102,102,106,99,99,101,102,103,106,99,101,102,99,106,99,95,103,106,99,101,102,106,106,101,102,103,106,101,102,106,99,101,101,110,99,101,102,99,103,106,99,101,102,103,106,99,101,102,103,106,99,101,102,106,103,106,99,101,102,106,106,151,0,0,113,113,113,113,104,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,104,104,104,104,104,104,113,113,113,104,113,113,113,104,113,113,113,113,113,113,113,113,116,0,0,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,93,116,116,116,116,116,116,117,0,117,0,0,117,85,0,152,117,152,117,117,117,117,117,117,117,117,117,117,117,152,117,117,117,117,117,152,117,117,117,117,117,117,85,117,117,117,152,117,152,117,152,117,152,117,84,86,0,86,115,123,128,123,128,115,115,123,128,115,115,115,123,128,115,0,0,0,0,0,115,115,123,128,115,79,123,123,115,123,123,123,115,79,79,79,79,79,115,79,123,128,129,115,79,123,128,129,115,115,79,123,128,129,115,79,123,128,129,115,115,128,123,128,123,123,123,123,128,128,128,128,115,115,79,123,128,128,129,115,79,123,128,129,128,115,128,79,115,79,115,79,123,128,129,79,129,123,79,79,79,79,79,79,79,123,129,123,79,115,128,115,79,79,115,79,123,128,129,115,128,115,79,123,128,128,129,115,79,123,128,129,115,79,123,128,129,115,79,123,128,129,153,154,153,155,154,156,157,158,159,157,155,114,114,114,0,114,114,114,0,114,114,91,114,91,114,114,91,114,114,91,114,114,114,114,114,114,91,114,91,114,91,91,91,91,91,114,114,91,114,91,114,91,91,114,91,114,160,160,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,0,111,111,111,111,111,111,111,111,111,111,111,111,111,0,111,111,111,111,111,111,111,111,111,111,111,136,136,111,136,111,136,111,136,111,136,111,136,136,111,111,111,111,111,111,111,111,111,111,136,136,111,111,111,136,111,111,111,111,136,136,111,136,111,111,111,111,111,111,136,111,136,111,136,111,111,136,111,136,111,136,111,136,0,140,140,140,140,140,140,140,140,0,0,0,140,140,140,140],"f":"``````````````````````````````````````````{{bb}d}```{fb}{hb}{jb}2{ll}03``{ce{}{}}00000000000{fn}{A`n}{ff}{jj}{{{Ab{c}}}{{Ab{c}}}Ad}{AfAf}{{ce}Ah{}{}}000{{ff}Aj}{{ce}Aj{}{}}>{{bb{An{{Al{bb}}}}}{{Bd{B`Bb}}}}{A`{{Bj{{Bh{Bf}}}}}}{c{{Bd{f}}}Bl}{c{{Bd{j}}}Bl}1`{f{{Bn{b}}}}{{ff}n}{{ce}n{}{}}000`{{fC`}{{Bd{AhCb}}}}0{{CdC`}Cf}{{hC`}Cf}{{jC`}Cf}{{jC`}{{Bd{AhCb}}}}{{AfC`}Cf}8{cc{}}00000{Ch{{Bd{CdCj}}}}0{c{{Bd{fAh}}}{{Cn{Cl}}}}0{b{{Bd{fD`}}}}{b{{Bd{Afc}}}{}}{bd}{{}{{Bn{Db}}}}{fn}0{{fc}AhDd}{{ce}{{Df{eg}}}{}{DhDjDl}{}}0```{{{E`{Dn}}}{{Bd{EbEd}}}}{f{{Bn{{Ef{b}}}}}}{f{{Bn{b}}}}`{{fEh}b}{{f{El{Ej}}}b}{{f{En{Ej}}}b}{{f{F`{Ej}}}b}{nAh}{ce{}{}}00000{f{{Bd{{Fb{Ah}}Fd}}}}0{f{{Bd{{Ff{Ah}}Fh}}}}0{c{{Fl{Fj}}}{}}{fFj}{Afn}{fn}{{fb}{{Bd{fD`}}}}{ClA`}{{ff}{{Bn{Fj}}}}``{{bAf}Af}{{}Fn}{bd}{fG`}{b{{Bd{fD`}}}}{{bc}{{Bd{fD`}}}Gb}{{ff}{{Bn{Aj}}}}{f{{Bn{b}}}}{fb}{f{{Bn{{Gf{Gd}}}}}}{f{{Bd{GhAh}}}}{f{{Bn{Gj}}}}04{fGl}{f{{H`{Gn}}}}```5{{fc}BdHb}0{{f{Bn{b}}}Ah}{{f{Bn{b}}}{{Bd{AhD`}}}}{{fHd}{{Bd{AhAh}}}}{{f{Bn{b}}}{{Bd{AhAh}}}}{{fb}Ah}{{f{Bn{Gj}}}{{Bd{AhAh}}}}5{{fb}{{Bd{AhAh}}}}0`{{fc}{{Bd{{Hh{Hf}}Hj}}}{{Hn{}{{Hl{{Bn{Gj}}}}}}}}``{f{{Bd{dAh}}}}{f{{Bd{Hj}}}}{ce{}{}}000{cFj{}}0{c{{Bd{e}}}{}{}}{b{{Bd{f}}}}11111{b{{Bd{Afc}}}{}}222222{cI`{}}00000{{CdCh}{{Bd{AhCj}}}}0{fb}777777{{fIbIb}Ah}`````````````````{cId{}}{{{If{ceg}}bk}{{Bd{{If{ceg}}Ih}}}{DjDl}{}{DjDlIj}Il{DjDl{Hn{Inc}{{Hl{{J`{{Bd{ie}}}}}}}}}}{Ih{{Bn{Jb}}}};;;;;;;;{Ih{{Bn{Id}}}}{IhIh}{JdJd}{JfJf}{{ce}Ah{}{}}00{{}Jf}{{{If{ceg}}bk}{{Bd{{If{ceg}}Ih}}}{DjDlJh}{}{DjDlIj}Il{DjDl{Hn{In}{{Hl{{J`{{Bd{ie}}}}}}}}}}{Ihb}`{c{{Bd{Jd}}}Bl}{c{{Bd{Jf}}}Bl}{{IhIh}n}{{JdJd}n}{{ce}n{}{}}0000000{{IhC`}Cf}0{{JdC`}Cf}{{JfC`}Cf}{{{If{ceg}}C`}Cf{}{}{}}`{cc{}}000{c{{Bd{{If{egi}}Ih}}}{{Cn{Cl}}}{}{}Ij}{{{If{ceg}}bk}{{Bd{{If{ceg}}Ih}}}{DjDlJj}{}{DjDlIj}Il{DjDl{Hn{In}{{Hl{{J`{{Bd{ie}}}}}}}}}}{{ce}{{Df{eg}}}{}{DhDjDl}{}}``````{c{}{}}{ce{}{}}000{{{If{ceg}}bk}{{Bd{{If{ceg}}Ih}}}{DjDlJj}{}{DjDlIj}{AdJl}{DjDl{Hn{In}{{Hl{{J`{{Bd{{Jn{i}}e}}}}}}}}}}`{c{{Bd{{If{egi}}Ih}}}{{K`{A`}}}{}{}Ij}````{{{If{ceg}}bk}{{Bd{{If{ceg}}Ih}}}{DjDlJh}{}{DjDlIj}Il{DjDl{Hn{In}{{Hl{{J`{{Bd{ie}}}}}}}}}}0`{{Jdc}BdHb}{{Jfc}BdHb}{{{If{ceg}}bm}{{Bd{{If{ceg}}Ih}}}{DjDl}{DjDh}Ij{IlKb}Kd{DjDl{Hn{In{Kf{ikeg}}c}{{Hl{{J`{{Bd{Ahe}}}}}}}}}}{Ih{{Bn{Id}}}}`{{{If{ceg}}bk}{{Bd{{If{ceg}}Ih}}}{DjDl}{DjDh}{DjDlIj}{IlDjDl}{DjDl{Hn{Inc}{{Hl{{Kh{{Bd{ie}}}}}}}}}}888{cFj{}}{c{{Bd{e}}}{}{}}0000000{cI`{}}000;;;;{{{If{ceg}}k}{{If{ceg}}}{DjDl}{}{DjDlIj}Kj{DjDl{Hn{c}{{Hl{{J`{i}}}}}}}}{{{If{ceg}}d}{{If{ceg}}}{}{}Ij}{{{If{ceg}}Kl}{{If{ceg}}}{}{}Ij}`````````````````{Kn{{Ld{{Lb{L`}}}}}}`{cId{}}{Lf{{Bn{Jb}}}}{{Kn{Lh{c}}}{{Ld{{Lb{L`}}}}}{DjDl}}{ce{}{}}000000000{Lf{{Bn{Id}}}}{LfLf}{LjLj}{LlLl}{{ce}Ah{}{}}00{{{Ln{cgei}}}k{DjDl}{DjDl}{M`{Mb{e}}}Ij{}}0{Lfb}{c{{Bd{Lj}}}Bl}{c{{Bd{Ll}}}Bl}`{{{Ln{cgei}}}Ah{DjDl}{DjDl}{M`{Mb{e}}}Ij}{{LfLf}n}{{LjLj}n}{{LlLl}n}{{ce}n{}{}}00000000000{{{Md{ce}}C`}CfMfMf}{{LfC`}Cf}0{{LjC`}Cf}{{LlC`}Cf}{cc{}}0000{{ce}{{Df{eg}}}{}{DhDjDl}{}}{{{Md{ce}}Inc}Lj{DjDl}{}}{c{}{}}{Kn{{Hh{Mh}}}}{ce{}{}}0000{{{Md{cg}}bi}{{Bd{{Ln{cgek}}Lf}}}{DjDl}{DjDl}{M`{Mb{e}}}{{K`{A`}}}Ij}{{{Md{ce}}Incb{Bn{Ib}}}{{Bn{Eb}}}{DjDl}{}}``{{{Ln{cgei}}}{{Bd{AhLf}}}{DjDl}{DjDl}{M`{Mb{e}}}Ij}{{{Md{cg}}b{If{cei}}}{{Bd{{Md{cg}}Lf}}}{DjDl}{DjDl}{M`{Mb{e}}}Ij}{{Ljc}BdHb}{{Llc}BdHb}{{{Md{ce}}gi}{{Mj{Ah}}}{DjDl}M`{{Ml{{Bj{{Md{ce}}}}}}}Ij}{Lf{{Bn{Id}}}}{LjMn}`{{{Ml{}{{N`{c}}}}}{{Bd{cHj}}}{{Kn{e}}}{AdDjDl}}:::{cFj{}}{c{{Bd{e}}}{}{}}000000000{cI`{}}0000{{{Md{ce}}}Ll{DjDl}{}}>>>>>{c{{Md{ce}}}{DjDl}{}}{{{Md{ce}}Kl}{{Md{ce}}}{DjDl}{}}```{cId{}}{Nb{{Bn{Jb}}}}{ce{}{}}0{{MnFj}M`}{{MnFj}Nb}{Nb{{Bn{Id}}}}{NbNb}{{ce}Ah{}{}}{Nbb}{c{{Bd{Nb}}}Bl}{{NbNb}n}{{ce}n{}{}}000{{NbC`}Cf}0{HjNb}{cc{}}{{{Nd{c}}}NbDh}{NfNb}{BbNb}{BbM`}{HjM`}{NfM`}{{{`{c}}}M`Dh}{EdM`}{{{Nd{c}}}M`Dh}{{ce}{{Df{eg}}}{}{DhDjDl}{}}{c{}{}}{ce{}{}}{M`Ed}`{{Nbc}BdHb}{Nb{{Bn{Id}}}}{M`Mn}{NbMn}`5{cFj{}}{c{{Bd{e}}}{}{}}0{cI`{}}8````````88{NhNh}{{ce}Ah{}{}}{{}Nh}{c{{Bd{Nh}}}Bl}{{NhNh}n}{{ce}n{}{}}000{{NhC`}Cf}{cc{}}{ce{}{}}{{Nhc}BdHb}{KjMn}{NhMn}3==<3````````3333{NjNj};{{}Nj}{{NjNj}n}9999{{NjC`}Cf}08{NlNj}9{b{{Bd{Njc}}}{}}4{{ce}{{Df{eg}}}{}{DhDjDl}{}}::{Njn}0666{{{Jj{}{{Nn{c}}}}g}{{Ld{{Lb{L`}}}}}{}{}{Dj{O`{c}{{Hl{{J`{e}}}}}}}}7<{cFj{}}{c{{Bd{e}}}{}{}}000{cI`{}}0??{{Jhg}{{Ld{{Lb{L`}}}}}{}{}{Dj{O`{c}{{Hl{{J`{e}}}}}}}}``{{{Jl{}{{Ob{c}}}}}{{Bd{Fjc}}}{MfId}}`````````````````````````{In{{Bd{OdNf}}}}{Of{{Bd{cNf}}}{{Oj{Oh}}}}{Of{{Bd{nNf}}}}{cId{}}{Of{{Bd{cNf}}}{{Oj{Ol}}}}{Of{{Bd{bNf}}}}{Of{{Bd{OhNf}}}}{Nf{{Bn{Jb}}}}{{Inc}{{Bd{eNf}}}{KbDh}{{Oj{Oh}}}}{{Inc}{{Bd{eNf}}}IjKd}{In{{Hh{On}}}}{In{{Bd{cNf}}}Kd}{{Inc}{{Bd{nNf}}}{KbDh}}{ce{}{}}000000000{Nf{{Bn{Id}}}}{NfNf}{InIn}{OfOf}{A`A`}{AbAb}{{ce}Ah{}{}}0000{Nfb}{c{{Bd{Nf}}}Bl}{c{{Bd{A`}}}Bl}{{OfOf}n}{{A`A`}n}{{ce}n{}{}}0000000{{NfC`}Cf}0{{InC`}Cf}{{OfC`}Cf}{{A`C`}{{Bd{AhCb}}}}{{A`C`}Cf}{{AbC`}Cf}{cc{}}0000{b{{Bd{A`c}}}{}}{{ce}{{Df{eg}}}{}{DhDjDl}{}}0{InAd}{c{}{}}{{Inc}{{Bd{eNf}}}{KbDh}{{Oj{Ol}}}}{ce{}{}}0000{InNj}`{{{E`{c}}Ab}{{Bd{{Bn{Of}}Nf}}}{}}{{Inc}{{Bd{{Bn{e}}Nf}}}{KbDh}{{Oj{Oh}}}}{{Inc}{{Bd{{Bn{n}}Nf}}}{KbDh}}{{Inc}{{Bd{{Bn{e}}Nf}}}{KbDh}{{Oj{Ol}}}}{{Inc}{{Bn{Of}}}{KbDh}}{{Inc}{{Bd{{Bn{b}}Nf}}}{KbDh}}{{Inc}{{Bd{{Bn{Oh}}Nf}}}{KbDh}}{{Inc}{{Bd{OfNf}}}{KbDh}}{OfA`}`{{bAb}{{Bd{OfNf}}}}{In{{Bn{b}}}}{{Nfc}BdHb}{{A`c}BdHb}{Nf{{Bn{Id}}}}{{Inc}{{Bd{bNf}}}{KbDh}}{{Inc}{{Bd{OhNf}}}{KbDh}}{ce{}{}}0000{cFj{}}0{c{{Bd{e}}}{}{}}000{b{{Bd{A`c}}}{}}111111{cI`{}}000044444`````````````````````4444{{{Nd{c}}}Af{}}{{{Kf{cegi}}}AhKb{}{}Ij}{{{Nd{c}}C`}CfMf}{{{Nd{c}}C`}CfDh}{cc{}}{Fh{{Nd{c}}}{}}{Ah{{Nd{c}}}{}}{Nf{{Nd{c}}}{}}3{Aj{{Nd{c}}}{}}{{ce}{{Df{eg}}}{}{DhDjDl}{}}>>>{{{Nd{c}}g}{{Nd{e}}}{}{}{{Hn{c}{{Hl{e}}}}}}{{{Ld{{Kf{cegi}}}}Al}{{An{{Bd{Ahk}}}}}{IlKb}{}{}Ij{}}0{{{Ld{{Kf{cegi}}}}Al}{{An{{Bn{k}}}}}KbKd{}Ij{}}1{{{Ld{{Kf{cegi}}}}c}{{Bd{Ahk}}}{IlKb}{}{}Ij{}}{{{Nd{c}}}Mn{}}{cFj{}}{c{{Bd{e}}}{}{}}000{{{Ld{c}}Al}{{An{{Bn{Bd}}}}}{}}{cI`{}}0{ce{}{}}0```````````````````````````````````````````````````````````````{cId{}}{AA`{{Bn{Jb}}}}2222{Mnb}{AA`{{Bn{Id}}}}{MnMn}{AA`AA`}{{ce}Ah{}{}}0{AA`b}{c{{Bd{Mn}}}Bl}{{MnMn}n}{{MnAAb}n}{{MnAAd}n}{{ce}n{}{}}000{{MnC`}Cf}0{{AA`C`}Cf}0{AAbMn}{AAdMn}{cc{}}0{AAf{{Bn{Mn}}}}{Ib{{Bn{Mn}}}}{{Mnc}AhDd}{{ce}{{Df{eg}}}{}{DhDjDl}{}}0{c{}{}}{ce{}{}}0{Mnn}0000{{Mnc}BdHb}{AA`{{Bn{Id}}}}33{cFj{}}0{Gj{{Bd{Mnc}}}{}}{c{{Bd{e}}}{}{}}000{cI`{}}077`77={{AAhb}AAj}8{fAAh}1{{AAhNlb}AAj}{{}Ah}{f{{AAn{AAl}}}}{{f{An{{Al{AB`b}}}}}{{AAn{AAl}}}}776=","c":[143],"p":[[1,"str"],[5,"PathBuf",921],[5,"Url",0],[6,"DiscoKey",0],[6,"HealthStatus",0],[5,"Command",922],[1,"bool"],[6,"Value",923],[5,"ServerState",0],[10,"Clone",924],[6,"UrlSegment",0],[1,"unit"],[6,"Ordering",925],[1,"tuple"],[1,"slice"],[5,"Config",926],[6,"ConfigError",927],[6,"Result",928],[1,"usize"],[5,"Router",929],[5,"Arc",930],[10,"Deserializer",931],[6,"Option",932],[5,"Formatter",933],[5,"Error",933],[5,"DiscoArgs",0],[8,"Result",933],[5,"ArgMatches",934],[8,"Error",935],[5,"Path",921],[10,"AsRef",936],[6,"ParseError",937],[5,"Id",938],[10,"Hasher",939],[5,"IndentedSection",940],[10,"Display",933],[10,"Send",941],[10,"Sync",941],[8,"AppServerState",0],[5,"Request",942],[5,"Response",943],[5,"Error",944],[6,"Host",945],[5,"RangeFull",946],[6,"Position",947],[5,"RangeFrom",946],[5,"RangeTo",946],[5,"Range",946],[5,"Request",948],[6,"Error",949],[5,"Request",948],[6,"Error",949],[5,"String",950],[6,"Resettable",951],[5,"ParseOptions",952],[6,"Origin",953],[10,"IntoIterator",954],[1,"char"],[5,"Split",955],[5,"PathSegmentsMut",956],[1,"u16"],[5,"Parse",957],[5,"UrlQuery",952],[5,"Serializer",957],[10,"Serializer",958],[6,"IpAddr",959],[6,"SocketAddr",960],[5,"Vec",961],[5,"Error",962],[17,"Output"],[10,"Fn",963],[5,"TypeId",964],[1,"u64"],[10,"Error",965],[5,"Api",224],[6,"ApiError",224],[10,"StaticVersionType",966],[10,"Serialize",958],[5,"RequestParams",587],[8,"BoxFuture",967],[5,"Backtrace",968],[5,"ApiVersion",224],[5,"ApiMetadata",224],[10,"WriteState",536],[10,"ReadState",536],[10,"Metrics",584],[6,"Cow",969],[10,"Into",936],[10,"Sized",941],[10,"DeserializeOwned",931],[5,"Connection",740],[8,"BoxStream",970],[10,"HealthCheck",506],[5,"Version",971],[10,"Listener",345],[10,"Future",972],[5,"Box",973],[5,"Pin",974],[6,"AppError",345],[5,"Server",975],[5,"AppHealth",345],[5,"AppVersion",345],[5,"Module",345],[10,"Error",459],[10,"From",936],[5,"App",345],[10,"Debug",933],[5,"ListenInfo",976],[8,"Result",962],[10,"ToListener",345],[6,"StatusCode",787],[17,"Listener"],[5,"ServerError",459],[6,"SocketError",740],[6,"RequestError",587],[6,"HealthStatus",506],[6,"Method",536],[6,"Method",977],[17,"State"],[10,"FnOnce",963],[17,"Error"],[5,"Accept",978],[6,"RequestParamValue",587],[5,"TaggedBase64",979],[10,"TryFrom",936],[1,"u128"],[1,"u8"],[6,"RequestParamType",587],[5,"RequestParam",587],[5,"Headers",980],[6,"CloseCode",981],[5,"Error",982],[5,"Error",983],[5,"Context",984],[6,"Poll",985],[5,"OutOfRangeError",787],[5,"StatusCode",986],[6,"StatusCode",987],[1,"i64"],[5,"Client",905],[5,"RequestBuilder",988],[8,"ConnectStream",989],[5,"WebSocketStream",990],[5,"HeaderName",991],[8,"AppState",0],[15,"IncorrectMethod",338],[15,"CannotReadToml",338],[15,"AmbiguousRoutes",338],[15,"Route",338],[15,"InvalidMetaTable",338],[15,"Api",458],[5,"ParseMethodError",536],[15,"IncorrectParamType",729],[15,"TagMismatch",729],[15,"IntegerOverflow",729],[15,"MissingParam",729],[15,"InvalidParam",729],[15,"TaggedBase64",729],[15,"Http",729],[15,"IncorrectMethod",785]],"b":[[93,"impl-Display-for-Url"],[94,"impl-Debug-for-Url"],[97,"impl-Debug-for-HealthStatus"],[98,"impl-Display-for-HealthStatus"],[127,"impl-Index%3CRangeFull%3E-for-Url"],[128,"impl-Index%3CRangeFrom%3CPosition%3E%3E-for-Url"],[129,"impl-Index%3CRangeTo%3CPosition%3E%3E-for-Url"],[130,"impl-Index%3CRange%3CPosition%3E%3E-for-Url"],[138,"impl-IntoClientRequest-for-%26Url"],[139,"impl-IntoClientRequest-for-Url"],[140,"impl-IntoClientRequest-for-Url"],[141,"impl-IntoClientRequest-for-%26Url"],[275,"impl-Debug-for-ApiError"],[276,"impl-Display-for-ApiError"],[400,"impl-Display-for-AppError"],[401,"impl-Debug-for-AppError"],[477,"impl-Display-for-ServerError"],[478,"impl-Debug-for-ServerError"],[479,"impl-From%3CError%3E-for-ServerError"],[481,"impl-From%3CSocketError%3CE%3E%3E-for-ServerError"],[482,"impl-From%3CRequestError%3E-for-ServerError"],[483,"impl-From%3CConfigError%3E-for-ServerError"],[556,"impl-Debug-for-Method"],[557,"impl-Display-for-Method"],[659,"impl-Display-for-RequestError"],[660,"impl-Debug-for-RequestError"],[663,"impl-Display-for-RequestParamType"],[664,"impl-Debug-for-RequestParamType"],[756,"impl-Debug-for-SocketError%3CE%3E"],[757,"impl-Display-for-SocketError%3CE%3E"],[759,"impl-From%3CError%3E-for-SocketError%3CE%3E"],[760,"impl-From%3CError%3E-for-SocketError%3CE%3E"],[761,"impl-From%3CRequestError%3E-for-SocketError%3CE%3E"],[763,"impl-From%3CError%3E-for-SocketError%3CE%3E"],[862,"impl-PartialEq-for-StatusCode"],[863,"impl-PartialEq%3CStatusCode%3E-for-StatusCode"],[864,"impl-PartialEq%3CStatusCode%3E-for-StatusCode"],[869,"impl-Display-for-StatusCode"],[870,"impl-Debug-for-StatusCode"],[871,"impl-Debug-for-OutOfRangeError"],[872,"impl-Display-for-OutOfRangeError"],[873,"impl-From%3CStatusCode%3E-for-StatusCode"],[874,"impl-From%3CStatusCode%3E-for-StatusCode"]]}]\
+["tide_disco",{"doc":"Tide Disco is a web server framework with built-in …","t":"EEIIPPPPPFGEPGPIPPPEEEEEESSFPEPPPPFGOPCOPCHOOPNNNNNNNOPNNNNNNNNNNNNNHNNNNNNNNNNHHHNNNPNNNNNNCNNNNNNNNNNNNNNNNNNNNHNNNNNNOOCHNNENNNNHNNNNNNNNNNNNNNNQHNCCNNHNNNNNNNNNNNNNCOONNNNNNNNNNNNCNCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHPFGFPFPPPPPPPPPPONNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNONNNNNNNOOOOOONNNNNNONOOOONNONNNNONNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOPFGFFPKRFKMONNMNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNOONNNNNNNOMNNNNNNNNNNNNNNNNNNNNNNNNNNNOOKFNNNNMNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNMNONNNNNNPKGPPPPPNNNNNNNNNNNNNNNMNNNNNNPGPFKPRKNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNNNMRKMPPPPPPPPPPPPPPPGFGGFPPPPPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOPPPFPPPGPPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPFPPPPPPPPPPPPPGPPPPPPPPPPPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNFNNNNNNNNHHHNNNN","n":["Api","App","AppServerState","AppState","Array","Available","Boolean","Boolean","Datetime","DiscoArgs","DiscoKey","Error","Float","HealthStatus","Hexadecimal","Html","Integer","Integer","Literal","Method","RequestError","RequestParam","RequestParamType","RequestParamValue","RequestParams","SERVER_STARTUP_RETRIES","SERVER_STARTUP_SLEEP_MS","ServerState","Starting","StatusCode","Stopping","String","Table","TaggedBase64","Url","UrlSegment","ansi_color","ansi_color","api","api_toml","api_toml","app","app_api_path","app_state","app_state","app_toml","as_ref","as_ref","as_ref","as_str","augment_args","augment_args_for_update","authority","base_url","base_url","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","cannot_be_a_base","check_api","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","cmp","compare","compose_config_path","compose_settings","configure_router","deserialize","deserialize","deserialize_internal","disco_toml","domain","eq","equivalent","equivalent","equivalent","equivalent","error","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fragment","from","from","from","from","from","from","from_arg_matches","from_arg_matches_mut","from_directory_path","from_file_path","from_str","from_str","get_api_path","group_id","has_authority","has_host","hash","header","header","health_status","health_status","healthcheck","healthcheck","host","host_str","http","index","index","index","index","init_logging","into","into","into","into","into","into","into_client_request","into_client_request","into_client_request","into_client_request","into_resettable","into_string","is_bound","is_special","join","join","load_api","make_relative","method","metrics","new","options","org_data_path","origin","parse","parse_with_params","partial_cmp","password","path","path_segments","path_segments_mut","port","port_or_known_default","query","query_pairs","query_pairs_mut","request","router","router","scheme","serialize","serialize_internal","set_fragment","set_host","set_ip_host","set_password","set_path","set_port","set_query","set_scheme","set_username","socket","socket_addrs","status","testing","to_file_path","to_listener","to_owned","to_owned","to_owned","to_owned","to_string","to_string","try_from","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","type_id","type_id","type_id","type_id","type_id","type_id","update_from_arg_matches","update_from_arg_matches_mut","username","vzip","vzip","vzip","vzip","vzip","vzip","wait_for_server","AmbiguousRoutes","Api","ApiError","ApiMetadata","ApiMustBeTable","ApiVersion","CannotReadToml","HandlerAlreadyRegistered","IncorrectMethod","InvalidFormatVersion","InvalidMetaTable","MissingFormatVersion","MissingRoutesTable","Route","RoutesMustBeTable","UndefinedRoute","api_version","as_error_source","at","backtrace","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","cause","clone","clone","clone","clone_into","clone_into","clone_into","default","delete","description","description","deserialize","deserialize","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","format_version","from","from","from","from","from_file","get","header","heading_description","heading_entry","heading_parameters","heading_routes","html_bottom","html_top","in_current_span","into","into","into","into","metrics","name","new","parameter_none","parameter_row","parameter_table_close","parameter_table_open","post","put","route_path","serialize","serialize","socket","source","spec_version","stream","to_owned","to_owned","to_owned","to_string","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","with_health_check","with_public","with_version","actual","expected","reason","route1","route2","source","source","Api","App","AppError","AppHealth","AppVersion","Dispatch","Listener","Listener","Module","ToListener","accept","app_version","as_error_source","backtrace","bind","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","cause","clone","clone","clone","clone_into","clone_into","clone_into","deref","deref_mut","description","deserialize","deserialize","disco_version","drop","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","header","health","in_current_span","info","into","into","into","into","into","module","module_health","modules","modules","register","register_module","serialize","serialize","serve","source","status","status","to_listener","to_owned","to_owned","to_owned","to_string","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","version","vzip","vzip","vzip","vzip","vzip","with_state","with_version","source","source","Error","ServerError","as_error_source","backtrace","borrow","borrow_mut","catch_all","catch_all","cause","clone","clone_into","description","deserialize","eq","equivalent","equivalent","equivalent","equivalent","fmt","fmt","from","from","from","from","from","from_config_error","from_io_error","from_request_error","from_route_error","from_server_error","from_socket_error","header","in_current_span","into","into_tide_error","message","serialize","source","status","status","status","to_owned","to_string","try_from","try_into","type_id","vzip","Available","HealthCheck","HealthStatus","Initializing","ShuttingDown","TemporarilyUnavailable","Unavailabale","Unhealthy","borrow","borrow_mut","clone","clone_into","default","deserialize","eq","equivalent","equivalent","equivalent","equivalent","fmt","from","into","serialize","status","status","to_owned","try_from","try_into","type_id","vzip","Http","Method","Metrics","ParseMethodError","ReadState","Socket","State","WriteState","borrow","borrow","borrow_mut","borrow_mut","clone","clone_into","delete","eq","equivalent","equivalent","equivalent","equivalent","fmt","fmt","from","from","from","from_str","get","header","into","into","is_http","is_mutable","metrics","post","put","read","socket","to_owned","to_string","try_from","try_from","try_into","try_into","type_id","type_id","vzip","vzip","write","Error","Metrics","export","Binary","Boolean","Boolean","Hexadecimal","Hexadecimal","Http","IncorrectParamType","Integer","Integer","IntegerOverflow","InvalidParam","Json","Literal","Literal","MissingParam","RequestError","RequestParam","RequestParamType","RequestParamValue","RequestParams","TagMismatch","TaggedBase64","TaggedBase64","TaggedBase64","UnsupportedContentType","accept","as_blob","as_boolean","as_error_source","as_integer","as_string","as_tagged_base64","backtrace","blob_param","body_auto","body_bytes","body_json","boolean_param","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","cause","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","description","deserialize","deserialize","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from_str","header","header","headers","in_current_span","integer_param","into","into","into","into","into","method","name","new","opt_blob_param","opt_boolean_param","opt_integer_param","opt_param","opt_string_param","opt_tagged_base64_param","param","param_type","param_type","parse","remote","serialize","serialize","source","string_param","tagged_base64_param","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","actual","actual","expected","expected","expected","name","param_type","reason","reason","reason","value","AppSpecific","Binary","Closed","Connection","IncorrectMethod","Json","Request","SocketError","UnsupportedMessageType","WebSockets","borrow","borrow","borrow_mut","borrow_mut","code","drop","fmt","fmt","from","from","from","from","from","from","header","into","into","into_stream","map_app_specific","poll_close","poll_flush","poll_next","poll_ready","start_send","status","to_string","try_from","try_from","try_into","try_into","try_poll_next","type_id","type_id","vzip","vzip","actual","expected","Accepted","BadGateway","BadRequest","Conflict","Continue","Created","EarlyHints","ExpectationFailed","FailedDependency","Forbidden","Found","GatewayTimeout","Gone","HttpVersionNotSupported","ImATeapot","ImUsed","InsufficientStorage","InternalServerError","LengthRequired","Locked","LoopDetected","MethodNotAllowed","MisdirectedRequest","MovedPermanently","MultiStatus","MultipleChoice","NetworkAuthenticationRequired","NoContent","NonAuthoritativeInformation","NotAcceptable","NotExtended","NotFound","NotImplemented","NotModified","Ok","OutOfRangeError","PartialContent","PayloadTooLarge","PaymentRequired","PermanentRedirect","PreconditionFailed","PreconditionRequired","ProxyAuthenticationRequired","RequestHeaderFieldsTooLarge","RequestTimeout","RequestedRangeNotSatisfiable","ResetContent","SeeOther","ServiceUnavailable","StatusCode","SwitchingProtocols","TemporaryRedirect","TooEarly","TooManyRequests","Unauthorized","UnavailableForLegalReasons","UnprocessableEntity","UnsupportedMediaType","UpgradeRequired","UriTooLong","VariantAlsoNegotiates","as_error_source","backtrace","borrow","borrow","borrow_mut","borrow_mut","canonical_reason","cause","clone","clone","clone_into","clone_into","description","deserialize","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","from","from","from","from","from_i64","from_u64","hash","header","header","in_current_span","into","into","is_client_error","is_informational","is_redirection","is_server_error","is_success","serialize","source","to_owned","to_owned","to_string","to_string","try_from","try_from","try_from","try_into","try_into","type_id","type_id","vzip","vzip","Client","borrow","borrow_mut","from","get","into","new","post","request","setup_test","test_ws_client","test_ws_client_with_headers","try_from","try_into","type_id","vzip"],"q":[[0,"tide_disco"],[225,"tide_disco::api"],[339,"tide_disco::api::ApiError"],[346,"tide_disco::app"],[461,"tide_disco::app::AppError"],[463,"tide_disco::error"],[510,"tide_disco::healthcheck"],[540,"tide_disco::method"],[588,"tide_disco::metrics"],[591,"tide_disco::request"],[733,"tide_disco::request::RequestError"],[744,"tide_disco::socket"],[789,"tide_disco::socket::SocketError"],[791,"tide_disco::status"],[909,"tide_disco::testing"],[925,"std::path"],[926,"clap_builder::builder::command"],[927,"toml::value"],[928,"core::clone"],[929,"core::cmp"],[930,"config::config"],[931,"config::error"],[932,"core::result"],[933,"routefinder::router"],[934,"alloc::sync"],[935,"serde::de"],[936,"core::option"],[937,"core::fmt"],[938,"core::fmt"],[939,"clap_builder"],[940,"std::path"],[941,"url::parser"],[942,"clap_builder::util::id"],[943,"core::hash"],[944,"color_eyre::section"],[945,"core::fmt"],[946,"core::marker"],[947,"tide::response"],[948,"http_types::error"],[949,"url::host"],[950,"url::slicing"],[951,"core::ops::range"],[952,"core::ops::range"],[953,"tungstenite::error"],[954,"http::request"],[955,"clap_builder::builder::resettable"],[956,"url"],[957,"url::origin"],[958,"core::iter::traits::collect"],[959,"core::str::iter"],[960,"url::path_segments"],[961,"form_urlencoded"],[962,"url"],[963,"core::net::ip_addr"],[964,"core::net::socket_addr"],[965,"alloc::vec"],[966,"std::io::error"],[967,"core::ops::function"],[968,"core::any"],[969,"core::error"],[970,"vbs::version"],[971,"serde::ser"],[972,"std::backtrace"],[973,"alloc::borrow"],[974,"core::convert"],[975,"semver"],[976,"core::future::future"],[977,"alloc::boxed"],[978,"core::pin"],[979,"tide::server"],[980,"core::convert"],[981,"std::io::error"],[982,"core::ops::function"],[983,"tagged_base64"],[984,"core::convert"],[985,"tungstenite::protocol::frame::coding"],[986,"serde_json::error"],[987,"anyhow"],[988,"core::task::wake"],[989,"core::task::poll"],[990,"http::status"],[991,"http_types::status_code"],[992,"reqwest::async_impl::request"],[993,"async_tungstenite::async_std"],[994,"async_tungstenite"],[995,"http::header::name"]],"d":["","","","","Represents a TOML array","","Represents a TOML boolean","","Represents a TOML datetime","","Configuration keys for Tide Disco settings","","Represents a TOML float","","","","Represents a TOML integer","","","","","","","","","Number of times to poll before failing","Number of milliseconds to sleep between attempts","","","","","Represents a TOML string","Represents a TOML table","","A parsed URL record.","","If true, log in color. Otherwise, no color.","","","HTTP routes","","","","","","","","","","Return the serialization of this URL.","","","Return the authority of this URL as an ASCII string.","Server address","","","","","","","","","","","","","","Return whether this URL is a cannot-be-a-base URL, meaning …","Check api.toml for schema compliance errors","","","","","","","","","","","Compose the path to the application’s configuration file","Get the application configuration","Add routes from api.toml to the routefinder instance in …","","","Serialize with Serde using the internal representation of …","","If this URL has a host and it is a domain name (not an IP …","","","","","","","","","","","","","","Return this URL’s fragment identifier, if any.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","Convert a directory name as std::path::Path
into an URL in …","Convert a file name as std::path::Path
into an URL in the …","","","Get the path to api.toml
","","Return whether the URL has an ‘authority’, which can …","Equivalent to url.host().is_some()
.","","","","","","","Return a JSON expression with status 200 indicating the …","Return the parsed representation of the host for this URL. …","Return the string representation of the host (domain or IP …","","","","","","","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","","","","","","Return the serialization of this URL.","","Return whether the URL is special (has a special scheme)","Parse a string as an URL, with this URL as the base URL.","","Load the web API or panic","Creates a relative URL if possible, with this URL as the …","Interfaces for methods of accessing to state.","Support for routes using the Prometheus metrics format.","","Return a default ParseOptions
that can fully configure the …","","Return the origin of this URL (…","Parse an absolute URL from a string.","Parse an absolute URL from a string and add params to its …","","Return the password for this URL, if any, as a …","Return the path for this URL, as a percent-encoded ASCII …","Unless this URL is cannot-be-a-base, return an iterator of …","Return an object with methods to manipulate this URL’s …","Return the port number for this URL, if any.","Return the port number for this URL, or the default port …","Return this URL’s query string, if any, as a …","Parse the URL’s query string, if any, as …","Manipulate this URL’s query string, viewed as a sequence …","","","","Return the scheme of this URL, lower-cased, as an ASCII …","","Serialize with Serde using the internal representation of …","Change this URL’s fragment identifier.","Change this URL’s host.","Change this URL’s host to the given IP address.","Change this URL’s password.","Change this URL’s path.","Change this URL’s port number.","Change this URL’s query string.","Change this URL’s scheme.","Change this URL’s username.","An interface for asynchronous communication with clients, …","Resolve a URL’s host and port number to SocketAddr
.","","","Assuming the URL is in the file
scheme or similar, convert …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Return the username for this URL (typically the empty …","","","","","","","Wait for the server to respond to a connection request","","A description of an API.","An error encountered when parsing or constructing an Api.","Metadata used for describing and documenting an API.","","Version information about an API.","","","","","","","","","","","The version of this API.","","Register a handler for a route.","","","","","","","","","","","","","","","","","","Register a handler for a DELETE route.","","A description of this API.","","","","","","","","","","","","","","","","","","The version of the Tide Disco API specification format.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Create an Api by reading a TOML specification from a file.","Register a handler for a GET route.","","The heading preceding documentation of a route description.","The heading for documentation of a route.","The heading preceding documentation of route parameters.","The heading preceding documentation of all routes in this …","HTML to be appended to automatically generated …","HTML to be prepended to automatically generated …","","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Register a handler for a METRICS route.","The name of this API.","Parse an API from a TOML specification.","Documentation to insert in the parameters section of a …","HTML formatting an entry in a table documenting the …","HTML closing a table documenting the parameters of a route.","HTML preceding the contents of a table documenting the …","Register a handler for a POST route.","Register a handler for a PUT route.","HTML formatting the path of a route.","","","Register a handler for a SOCKET route.","","The format version of the TOML specification used to load …","Register a uni-directional handler for a SOCKET route.","","","","","","","","","","","","","","","","","","","","","Set the health check handler for this API.","Serve the contents of dir
at the URL /public/{{NAME}}
.","Set the API version.","","","","","","","","","A tide-disco server application.","An error encountered while building an App.","The health status of an application.","Version information about an application.","","The Listener trait represents an implementation of http …","What listener are we converting into?","RAII guard to ensure a module is registered after it is …","ToListener represents any type that can be converted into a","Start accepting incoming connections. This method must be …","The version of this application.","","","Bind the listener. This starts the listening process by …","","","","","","","","","","","","","","","","","","","","","","","The version of the Tide Disco server framework.","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Check the health of each registered module in response to …","","Expose information about the connection. This should …","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Create and register an API module.","Check the health of the named module.","The status of each registered module, indexed by version.","The supported versions of each module registered with this …","Register this module with the linked app.","Register an API module.","","","Serve the App asynchronously.","","","The status of the overall application.","Transform self into a Listener
. Unless self is already …","","","","","","","","","","","","","","","","","","","","Get the version of this application.","","","","","","Create a new App with a given state.","Set the application version.","","","Errors which can be serialized in a response body.","The simplest possible implementation of Error.","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","","","","","","","","","","","","","Calls U::from(self)
.","","","","","","","","","","","","","","","A response to a healthcheck endpoint.","Common health statuses of an application.","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Calls U::from(self)
.","","The status of this health check.","","","","","","","","","","","A state which allows read access.","","The type of state which this type allows a caller to read.","A state which allows exclusive, write access.","","","","","","","The HTTP DELETE method.","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","","The HTTP GET method.","","Calls U::from(self)
.","Calls U::from(self)
.","Check if a method is a standard HTTP method.","Check if a request method implies mutable access to the …","The Tide Disco METRICS method.","The HTTP POST method.","The HTTP PUT method.","Do an operation with immutable access to the state.","The Tide Disco SOCKET method.","","","","","","","","","","","Do an operation with mutable access to the state.","","","","","","","","","","","","","","","","","","","","","","","Parameters passed to a route handler.","","","","","","The Accept header of this request.","","","","","","","","Get the value of a named parameter and convert it to a …","Deserialize the body of a request.","","","Get the value of a named parameter and convert it to a bool…","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","The headers of the incoming request.","","Get the value of a named parameter and convert it to an …","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","Calls U::from(self)
.","The Method used to dispatch the request.","","Parse a parameter from a Request.","Get the value of a named optional parameter and convert it …","Get the value of a named optional parameter and convert it …","Get the value of a named optional parameter and convert it …","Get the value of a named optional parameter.","Get the value of a named optional parameter and convert it …","Get the value of a named optional parameter and convert it …","Get the value of a named parameter.","","","","Get the remote address for this request.","","","","Get the value of a named parameter and convert it to a …","Get the value of a named parameter and convert it to …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","A connection facilitating bi-directional, asynchronous …","","","","An error returned by a socket handler.","","","","","","","","","","","Returns the argument unchanged.","","","","Returns the argument unchanged.","","","Calls U::from(self)
.","Calls U::from(self)
.","","","","","","","","","","","","","","","","","","","","","202 Accepted","502 Bad Gateway","400 Bad Request","409 Conflict","100 Continue","201 Created","103 Early Hints","417 Expectation Failed","424 Failed Dependency","403 Forbidden","302 Found","504 Gateway Timeout","410 Gone","505 HTTP Version Not Supported","418 I’m a teapot","226 Im Used","507 Insufficient Storage","500 Internal Server Error","411 Length Required","423 Locked","508 Loop Detected","405 Method Not Allowed","421 Misdirected Request","301 Moved Permanently","207 Multi-Status","300 Multiple Choice","511 Network Authentication Required","204 No Content","203 Non Authoritative Information","406 Not Acceptable","510 Not Extended","404 Not Found","501 Not Implemented","304 Not Modified","200 Ok","","206 Partial Content","413 Payload Too Large","402 Payment Required","308 Permanent Redirect","412 Precondition Failed","428 Precondition Required","407 Proxy Authentication Required","431 Request Header Fields Too Large","408 Request Timeout","416 Requested Range Not Satisfiable","205 Reset Content","303 See Other","503 Service Unavailable","Serializable HTTP status code.","101 Switching Protocols","307 Temporary Redirect","425 Too Early","429 Too Many Requests","401 Unauthorized","451 Unavailable For Legal Reasons","422 Unprocessable Entity","415 Unsupported Media Type","426 Upgrade Required","414 URI Too Long","506 Variant Also Negotiates","","","","","","","The canonical reason for a given status code","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","","Returns the argument unchanged.","","","","","","","Calls U::from(self)
.","Calls U::from(self)
.","Returns true
if the status code is the 4xx
range.","Returns true
if the status code is 1xx
range.","Returns true
if the status code is the 3xx
range.","Returns true
if the status code is the 5xx
range.","Returns true
if the status code is the 2xx
range.","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","","Calls U::from(self)
.","","","","","","","","","",""],"i":[0,0,0,0,145,5,145,11,145,0,0,0,145,0,11,0,145,11,11,0,0,0,0,0,0,0,0,0,5,0,5,145,145,11,0,0,26,4,0,26,4,0,0,39,9,4,3,4,5,3,26,26,3,26,4,3,26,4,5,9,11,3,26,4,5,9,11,3,0,3,5,9,11,3,5,9,11,3,3,0,0,0,3,5,3,4,3,3,3,3,3,3,0,3,3,26,4,5,5,11,3,3,26,4,5,9,11,26,26,3,3,3,11,0,26,3,3,3,3,5,39,9,0,0,3,3,0,3,3,3,3,0,3,26,4,5,9,11,3,3,3,3,3,3,11,3,3,0,0,3,0,0,11,3,0,3,3,3,3,3,3,3,3,3,3,3,3,3,0,39,9,3,3,3,3,3,3,3,3,3,3,3,3,0,3,0,0,3,3,3,5,9,11,3,5,3,3,26,4,5,9,11,11,3,26,4,5,9,11,3,26,4,5,9,11,26,26,3,3,26,4,5,9,11,0,76,0,0,0,76,0,76,76,76,76,76,76,76,76,76,76,82,76,75,76,76,82,83,75,76,82,83,75,76,76,82,83,76,82,83,83,75,76,83,82,83,76,82,76,76,76,76,82,82,82,82,76,76,82,83,75,83,76,82,83,75,75,75,76,83,83,83,83,83,83,76,76,82,83,75,75,83,75,83,83,83,83,75,75,83,82,83,75,76,82,75,76,82,83,76,76,82,83,75,76,82,83,75,76,82,83,75,76,82,83,75,75,75,75,146,146,147,148,148,149,150,99,0,0,0,0,99,0,110,0,0,95,102,99,99,95,106,99,101,102,103,106,99,101,102,103,99,99,101,102,99,101,102,103,103,99,101,102,102,103,99,101,102,99,99,99,99,101,101,101,101,102,102,102,102,106,99,99,101,102,103,106,99,99,101,102,103,99,106,99,95,106,99,101,102,103,106,106,101,102,103,106,101,102,106,99,101,101,110,99,101,102,99,106,99,101,102,103,106,99,101,102,103,106,99,101,102,103,106,106,99,101,102,103,106,106,151,152,0,0,113,113,113,113,104,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,104,104,104,104,104,104,113,113,113,104,113,113,113,104,113,113,113,113,113,113,113,113,116,0,0,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,93,116,116,116,116,116,116,117,0,117,0,0,117,85,0,153,117,153,117,117,117,117,117,117,117,117,117,117,117,153,117,117,117,117,117,153,117,117,117,117,117,117,85,117,117,117,153,117,153,117,153,117,153,117,84,86,0,86,115,123,128,123,128,115,115,123,128,115,115,115,123,128,115,0,0,0,0,0,115,115,123,128,115,79,123,123,115,123,123,123,115,79,79,79,79,79,115,79,123,128,129,115,79,123,128,129,115,115,79,123,128,129,115,79,123,128,129,115,115,128,123,128,123,123,123,123,128,128,128,128,115,115,79,123,128,128,129,115,79,123,128,129,128,115,128,79,115,79,115,79,123,128,129,79,129,123,79,79,79,79,79,79,79,123,129,123,79,115,128,115,79,79,115,79,123,128,129,115,128,115,79,123,128,128,129,115,79,123,128,129,115,79,123,128,129,115,79,123,128,129,154,155,154,156,155,157,158,159,160,158,156,114,114,114,0,114,114,114,0,114,114,91,114,91,114,114,91,114,114,91,114,114,114,114,114,114,91,114,91,114,91,91,91,91,91,114,114,91,114,91,114,91,91,114,91,114,161,161,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,0,111,111,111,111,111,111,111,111,111,111,111,111,111,0,111,111,111,111,111,111,111,111,111,111,111,136,136,111,136,111,136,111,136,111,136,111,136,136,111,111,111,111,111,111,111,111,111,111,136,136,111,111,111,136,111,111,111,111,136,136,111,136,111,111,111,111,111,111,136,111,136,111,136,111,111,136,111,136,111,136,111,136,0,140,140,140,140,140,140,140,140,0,0,0,140,140,140,140],"f":"``````````````````````````````````````````{{bb}d}```{fb}{hb}{jb}2{ll}03``{ce{}{}}00000000000{fn}{A`n}{ff}{jj}{{{Ab{c}}}{{Ab{c}}}Ad}{AfAf}{{ce}Ah{}{}}000{{ff}Aj}{{ce}Aj{}{}}>{{bb{An{{Al{bb}}}}}{{Bd{B`Bb}}}}{A`{{Bj{{Bh{Bf}}}}}}{c{{Bd{f}}}Bl}{c{{Bd{j}}}Bl}1`{f{{Bn{b}}}}{{ff}n}{{ce}n{}{}}000`{{fC`}{{Bd{AhCb}}}}0{{CdC`}Cf}{{hC`}Cf}{{jC`}Cf}{{jC`}{{Bd{AhCb}}}}{{AfC`}Cf}8{cc{}}00000{Ch{{Bd{CdCj}}}}0{c{{Bd{fAh}}}{{Cn{Cl}}}}0{b{{Bd{fD`}}}}{b{{Bd{Afc}}}{}}{bd}{{}{{Bn{Db}}}}{fn}0{{fc}AhDd}{{ce}{{Df{eg}}}{}{DhDjDl}{}}0```{{{E`{Dn}}}{{Bd{EbEd}}}}{f{{Bn{{Ef{b}}}}}}{f{{Bn{b}}}}`{{f{Ej{Eh}}}b}{{f{El{Eh}}}b}{{fEn}b}{{f{F`{Eh}}}b}{nAh}{ce{}{}}00000{f{{Bd{{Fb{Ah}}Fd}}}}{f{{Bd{{Ff{Ah}}Fh}}}}01{c{{Fl{Fj}}}{}}{fFj}{Afn}{fn}{{fb}{{Bd{fD`}}}}`{ClA`}{{ff}{{Bn{Fj}}}}``{{bAf}Af}{{}Fn}{bd}{fG`}{b{{Bd{fD`}}}}{{bc}{{Bd{fD`}}}Gb}{{ff}{{Bn{Aj}}}}{f{{Bn{b}}}}{fb}{f{{Bn{{Gf{Gd}}}}}}{f{{Bd{GhAh}}}}{f{{Bn{Gj}}}}04{fGl}{f{{H`{Gn}}}}```5{{fc}BdHb}0{{f{Bn{b}}}Ah}{{f{Bn{b}}}{{Bd{AhD`}}}}{{fHd}{{Bd{AhAh}}}}{{f{Bn{b}}}{{Bd{AhAh}}}}{{fb}Ah}{{f{Bn{Gj}}}{{Bd{AhAh}}}}5{{fb}{{Bd{AhAh}}}}0`{{fc}{{Bd{{Hh{Hf}}Hj}}}{{Hn{}{{Hl{{Bn{Gj}}}}}}}}``{f{{Bd{dAh}}}}{f{{Bd{Hj}}}}{ce{}{}}000{cFj{}}0{b{{Bd{f}}}}{c{{Bd{e}}}{}{}}00000{b{{Bd{Afc}}}{}}111111{cI`{}}00000{{CdCh}{{Bd{AhCj}}}}0{fb}777777{{fIbIb}Ah}`````````````````{cId{}}{{{If{ceg}}bk}{{Bd{{If{ceg}}Ih}}}{DjDl}{}{DjDlIj}Il{DjDl{Hn{Inc}{{Hl{{J`{{Bd{ie}}}}}}}}}}{Ih{{Bn{Jb}}}};;;;;;;;{Ih{{Bn{Id}}}}{IhIh}{JdJd}{JfJf}{{ce}Ah{}{}}00{{}Jf}{{{If{ceg}}bk}{{Bd{{If{ceg}}Ih}}}{DjDlJh}{}{DjDlIj}Il{DjDl{Hn{In}{{Hl{{J`{{Bd{ie}}}}}}}}}}{Ihb}`{c{{Bd{Jd}}}Bl}{c{{Bd{Jf}}}Bl}{{IhIh}n}{{JdJd}n}{{ce}n{}{}}0000000{{IhC`}Cf}0{{JdC`}Cf}{{JfC`}Cf}{{{If{ceg}}C`}Cf{}{}{}}`{cc{}}000{c{{Bd{{If{egi}}Ih}}}{{Cn{Cl}}}{}{}Ij}{{{If{ceg}}bk}{{Bd{{If{ceg}}Ih}}}{DjDlJj}{}{DjDlIj}Il{DjDl{Hn{In}{{Hl{{J`{{Bd{ie}}}}}}}}}}{{ce}{{Df{eg}}}{}{DhDjDl}{}}``````{c{}{}}{ce{}{}}000{{{If{ceg}}bk}{{Bd{{If{ceg}}Ih}}}{DjDlJj}{}{DjDlIj}{AdJl}{DjDl{Hn{In}{{Hl{{J`{{Bd{{Jn{i}}e}}}}}}}}}}`{c{{Bd{{If{egi}}Ih}}}{{K`{A`}}}{}{}Ij}````{{{If{ceg}}bk}{{Bd{{If{ceg}}Ih}}}{DjDlJh}{}{DjDlIj}Il{DjDl{Hn{In}{{Hl{{J`{{Bd{ie}}}}}}}}}}0`{{Jdc}BdHb}{{Jfc}BdHb}{{{If{ceg}}bm}{{Bd{{If{ceg}}Ih}}}{DjDl}{DjDh}Ij{IlKb}Kd{DjDl{Hn{In{Kf{ikeg}}c}{{Hl{{J`{{Bd{Ahe}}}}}}}}}}{Ih{{Bn{Id}}}}`{{{If{ceg}}bk}{{Bd{{If{ceg}}Ih}}}{DjDl}{DjDh}{DjDlIj}{IlDjDl}{DjDl{Hn{Inc}{{Hl{{Kh{{Bd{ie}}}}}}}}}}888{cFj{}}{c{{Bd{e}}}{}{}}0000000{cI`{}}000;;;;{{{If{ceg}}k}{{If{ceg}}}{DjDl}{}{DjDlIj}Kj{DjDl{Hn{c}{{Hl{{J`{i}}}}}}}}{{{If{ceg}}d}{{If{ceg}}}{}{}Ij}{{{If{ceg}}Kl}{{If{ceg}}}{}{}Ij}`````````````````{Kn{{Ld{{Lb{L`}}}}}}`{cId{}}{Lf{{Bn{Jb}}}}{{Kn{Lh{c}}}{{Ld{{Lb{L`}}}}}{DjDl}}{ce{}{}}000000000{Lf{{Bn{Id}}}}{LfLf}{LjLj}{LlLl}{{ce}Ah{}{}}00{{{Ln{cgei}}}k{DjDl}{DjDl}{M`{Mb{e}}}Ij{}}0{Lfb}{c{{Bd{Lj}}}Bl}{c{{Bd{Ll}}}Bl}`{{{Ln{cgei}}}Ah{DjDl}{DjDl}{M`{Mb{e}}}Ij}{{LfLf}n}{{LjLj}n}{{LlLl}n}{{ce}n{}{}}00000000000{{{Md{ce}}C`}CfMfMf}{{LfC`}Cf}0{{LjC`}Cf}{{LlC`}Cf}{{{Ln{cgei}}C`}Cf{DjDlMf}{DjDlMf}{M`{Mb{e}}Mf}{IjMf}}{cc{}}{IhLf}1111{{ce}{{Df{eg}}}{}{DhDjDl}{}}{{{Md{ce}}Inc}Lj{DjDl}{}}{c{}{}}{Kn{{Hh{Mh}}}}{ce{}{}}0000{{{Md{cg}}bi}{{Bd{{Ln{cgek}}Lf}}}{DjDl}{DjDl}{M`{Mb{e}}}{{K`{A`}}}Ij}{{{Md{ce}}Incb{Bn{Ib}}}{{Bn{Eb}}}{DjDl}{}}``{{{Ln{cgei}}}{{Bd{AhLf}}}{DjDl}{DjDl}{M`{Mb{e}}}Ij}{{{Md{cg}}b{If{cei}}}{{Bd{{Md{cg}}Lf}}}{DjDl}{DjDl}{M`{Mb{e}}}Ij}{{Ljc}BdHb}{{Llc}BdHb}{{{Md{ce}}gi}{{Mj{Ah}}}{DjDl}M`{{Ml{{Bj{{Md{ce}}}}}}}Ij}{Lf{{Bn{Id}}}}{LjMn}`{{{Ml{}{{N`{c}}}}}{{Bd{cHj}}}{{Kn{e}}}{AdDjDl}}:::{cFj{}}{c{{Bd{e}}}{}{}}000000000{cI`{}}0000{{{Md{ce}}}Ll{DjDl}{}}>>>>>{c{{Md{ce}}}{DjDl}{}}{{{Md{ce}}Kl}{{Md{ce}}}{DjDl}{}}````{cId{}}{Nb{{Bn{Jb}}}}{ce{}{}}0{{MnFj}M`}{{MnFj}Nb}{Nb{{Bn{Id}}}}{NbNb}{{ce}Ah{}{}}{Nbb}{c{{Bd{Nb}}}Bl}{{NbNb}n}{{ce}n{}{}}000{{NbC`}Cf}0{cc{}}{BbNb}{{{Nd{c}}}NbDh}{HjNb}{NfNb}{BbM`}{HjM`}{NfM`}{{{`{c}}}M`Dh}{EdM`}{{{Nd{c}}}M`Dh}{{ce}{{Df{eg}}}{}{DhDjDl}{}}{c{}{}}{ce{}{}}{M`Ed}`{{Nbc}BdHb}{Nb{{Bn{Id}}}}{M`Mn}{NbMn}`5{cFj{}}{c{{Bd{e}}}{}{}}0{cI`{}}8````````88{NhNh}{{ce}Ah{}{}}{{}Nh}{c{{Bd{Nh}}}Bl}{{NhNh}n}{{ce}n{}{}}000{{NhC`}Cf}{cc{}}{ce{}{}}{{Nhc}BdHb}{KjMn}{NhMn}3==<3````````3333{NjNj};{{}Nj}{{NjNj}n}9999{{NjC`}Cf}088{NlNj}{b{{Bd{Njc}}}{}}4{{ce}{{Df{eg}}}{}{DhDjDl}{}}::{Njn}0666{{{Jj{}{{Nn{c}}}}g}{{Ld{{Lb{L`}}}}}{}{}{Dj{O`{c}{{Hl{{J`{e}}}}}}}}7<{cFj{}}{c{{Bd{e}}}{}{}}000{cI`{}}0??{{Jhg}{{Ld{{Lb{L`}}}}}{}{}{Dj{O`{c}{{Hl{{J`{e}}}}}}}}``{{{Jl{}{{Ob{c}}}}}{{Bd{Fjc}}}{MfId}}`````````````````````````{In{{Bd{OdNf}}}}{Of{{Bd{cNf}}}{{Oj{Oh}}}}{Of{{Bd{nNf}}}}{cId{}}{Of{{Bd{cNf}}}{{Oj{Ol}}}}{Of{{Bd{bNf}}}}{Of{{Bd{OhNf}}}}{Nf{{Bn{Jb}}}}{{Inc}{{Bd{eNf}}}{KbDh}{{Oj{Oh}}}}{{Inc}{{Bd{eNf}}}IjKd}{In{{Hh{On}}}}{In{{Bd{cNf}}}Kd}{{Inc}{{Bd{nNf}}}{KbDh}}{ce{}{}}000000000{Nf{{Bn{Id}}}}{NfNf}{InIn}{OfOf}{A`A`}{AbAb}{{ce}Ah{}{}}0000{Nfb}{c{{Bd{Nf}}}Bl}{c{{Bd{A`}}}Bl}{{OfOf}n}{{A`A`}n}{{ce}n{}{}}0000000{{NfC`}Cf}0{{InC`}Cf}{{OfC`}Cf}{{A`C`}Cf}{{A`C`}{{Bd{AhCb}}}}{{AbC`}Cf}{cc{}}0000{b{{Bd{A`c}}}{}}{{ce}{{Df{eg}}}{}{DhDjDl}{}}0{InAd}{c{}{}}{{Inc}{{Bd{eNf}}}{KbDh}{{Oj{Ol}}}}{ce{}{}}0000{InNj}`{{{E`{c}}Ab}{{Bd{{Bn{Of}}Nf}}}{}}{{Inc}{{Bd{{Bn{e}}Nf}}}{KbDh}{{Oj{Oh}}}}{{Inc}{{Bd{{Bn{n}}Nf}}}{KbDh}}{{Inc}{{Bd{{Bn{e}}Nf}}}{KbDh}{{Oj{Ol}}}}{{Inc}{{Bn{Of}}}{KbDh}}{{Inc}{{Bd{{Bn{b}}Nf}}}{KbDh}}{{Inc}{{Bd{{Bn{Oh}}Nf}}}{KbDh}}{{Inc}{{Bd{OfNf}}}{KbDh}}{OfA`}`{{bAb}{{Bd{OfNf}}}}{In{{Bn{b}}}}{{Nfc}BdHb}{{A`c}BdHb}{Nf{{Bn{Id}}}}{{Inc}{{Bd{bNf}}}{KbDh}}{{Inc}{{Bd{OhNf}}}{KbDh}}{ce{}{}}0000{cFj{}}0{c{{Bd{e}}}{}{}}000{b{{Bd{A`c}}}{}}111111{cI`{}}000044444`````````````````````4444{{{Nd{c}}}Af{}}{{{Kf{cegi}}}AhKb{}{}Ij}{{{Nd{c}}C`}CfMf}{{{Nd{c}}C`}CfDh}{cc{}}{Nf{{Nd{c}}}{}}{Ah{{Nd{c}}}{}}{Fd{{Nd{c}}}{}}3{Aj{{Nd{c}}}{}}{{ce}{{Df{eg}}}{}{DhDjDl}{}}>>>{{{Nd{c}}g}{{Nd{e}}}{}{}{{Hn{c}{{Hl{e}}}}}}{{{Ld{{Kf{cegi}}}}Al}{{An{{Bd{Ahk}}}}}{IlKb}{}{}Ij{}}0{{{Ld{{Kf{cegi}}}}Al}{{An{{Bn{k}}}}}KbKd{}Ij{}}1{{{Ld{{Kf{cegi}}}}c}{{Bd{Ahk}}}{IlKb}{}{}Ij{}}{{{Nd{c}}}Mn{}}{cFj{}}{c{{Bd{e}}}{}{}}000{{{Ld{c}}Al}{{An{{Bn{Bd}}}}}{}}{cI`{}}0{ce{}{}}0```````````````````````````````````````````````````````````````{cId{}}{AA`{{Bn{Jb}}}}2222{Mnb}{AA`{{Bn{Id}}}}{MnMn}{AA`AA`}{{ce}Ah{}{}}0{AA`b}{c{{Bd{Mn}}}Bl}{{MnMn}n}{{MnAAb}n}{{MnAAd}n}{{ce}n{}{}}000{{MnC`}Cf}0{{AA`C`}Cf}0{AAbMn}{cc{}}{AAdMn}1{AAf{{Bn{Mn}}}}{Ib{{Bn{Mn}}}}{{Mnc}AhDd}{{ce}{{Df{eg}}}{}{DhDjDl}{}}0{c{}{}}{ce{}{}}0{Mnn}0000{{Mnc}BdHb}{AA`{{Bn{Id}}}}33{cFj{}}0{Gj{{Bd{Mnc}}}{}}{c{{Bd{e}}}{}{}}000{cI`{}}077`77>{{AAhb}AAj}8{fAAh}1{{AAhNlb}AAj}{{}Ah}{f{{AAn{AAl}}}}{{f{An{{Al{AB`b}}}}}{{AAn{AAl}}}}776=","c":[143],"p":[[1,"str"],[5,"PathBuf",925],[5,"Url",0],[6,"DiscoKey",0],[6,"HealthStatus",0],[5,"Command",926],[1,"bool"],[6,"Value",927],[5,"ServerState",0],[10,"Clone",928],[6,"UrlSegment",0],[1,"unit"],[6,"Ordering",929],[1,"tuple"],[1,"slice"],[5,"Config",930],[6,"ConfigError",931],[6,"Result",932],[1,"usize"],[5,"Router",933],[5,"Arc",934],[10,"Deserializer",935],[6,"Option",936],[5,"Formatter",937],[5,"Error",937],[5,"DiscoArgs",0],[8,"Result",937],[5,"ArgMatches",938],[8,"Error",939],[5,"Path",925],[10,"AsRef",940],[6,"ParseError",941],[5,"Id",942],[10,"Hasher",943],[5,"IndentedSection",944],[10,"Display",937],[10,"Send",945],[10,"Sync",945],[8,"AppServerState",0],[5,"Request",946],[5,"Response",947],[5,"Error",948],[6,"Host",949],[6,"Position",950],[5,"RangeFrom",951],[5,"Range",951],[5,"RangeFull",951],[5,"RangeTo",951],[5,"Request",952],[6,"Error",953],[5,"Request",952],[6,"Error",953],[5,"String",954],[6,"Resettable",955],[5,"ParseOptions",956],[6,"Origin",957],[10,"IntoIterator",958],[1,"char"],[5,"Split",959],[5,"PathSegmentsMut",960],[1,"u16"],[5,"Parse",961],[5,"UrlQuery",956],[5,"Serializer",961],[10,"Serializer",962],[6,"IpAddr",963],[6,"SocketAddr",964],[5,"Vec",965],[5,"Error",966],[17,"Output"],[10,"Fn",967],[5,"TypeId",968],[1,"u64"],[10,"Error",969],[5,"Api",225],[6,"ApiError",225],[10,"StaticVersionType",970],[10,"Serialize",962],[5,"RequestParams",591],[8,"BoxFuture",971],[5,"Backtrace",972],[5,"ApiVersion",225],[5,"ApiMetadata",225],[10,"WriteState",540],[10,"ReadState",540],[10,"Metrics",588],[6,"Cow",973],[10,"Into",940],[10,"Sized",945],[10,"DeserializeOwned",935],[5,"Connection",744],[8,"BoxStream",974],[10,"HealthCheck",510],[5,"Version",975],[10,"Listener",346],[10,"Future",976],[5,"Box",977],[5,"Pin",978],[6,"AppError",346],[5,"Server",979],[5,"AppHealth",346],[5,"AppVersion",346],[5,"Module",346],[10,"Error",463],[10,"From",940],[5,"App",346],[10,"Debug",937],[5,"ListenInfo",980],[8,"Result",966],[10,"ToListener",346],[6,"StatusCode",791],[17,"Listener"],[5,"ServerError",463],[6,"SocketError",744],[6,"RequestError",591],[6,"HealthStatus",510],[6,"Method",540],[6,"Method",981],[17,"State"],[10,"FnOnce",967],[17,"Error"],[5,"Accept",982],[6,"RequestParamValue",591],[5,"TaggedBase64",983],[10,"TryFrom",940],[1,"u128"],[1,"u8"],[6,"RequestParamType",591],[5,"RequestParam",591],[5,"Headers",984],[6,"CloseCode",985],[5,"Error",986],[5,"Error",987],[5,"Context",988],[6,"Poll",989],[5,"OutOfRangeError",791],[5,"StatusCode",990],[6,"StatusCode",991],[1,"i64"],[5,"Client",909],[5,"RequestBuilder",992],[8,"ConnectStream",993],[5,"WebSocketStream",994],[5,"HeaderName",995],[8,"AppState",0],[15,"IncorrectMethod",339],[15,"CannotReadToml",339],[15,"AmbiguousRoutes",339],[15,"Route",339],[15,"InvalidMetaTable",339],[15,"Api",461],[15,"Dispatch",461],[5,"ParseMethodError",540],[15,"IncorrectParamType",733],[15,"TagMismatch",733],[15,"IntegerOverflow",733],[15,"MissingParam",733],[15,"InvalidParam",733],[15,"TaggedBase64",733],[15,"Http",733],[15,"IncorrectMethod",789]],"b":[[93,"impl-Debug-for-Url"],[94,"impl-Display-for-Url"],[97,"impl-Debug-for-HealthStatus"],[98,"impl-Display-for-HealthStatus"],[127,"impl-Index%3CRangeFrom%3CPosition%3E%3E-for-Url"],[128,"impl-Index%3CRange%3CPosition%3E%3E-for-Url"],[129,"impl-Index%3CRangeFull%3E-for-Url"],[130,"impl-Index%3CRangeTo%3CPosition%3E%3E-for-Url"],[138,"impl-IntoClientRequest-for-Url"],[139,"impl-IntoClientRequest-for-%26Url"],[140,"impl-IntoClientRequest-for-Url"],[141,"impl-IntoClientRequest-for-%26Url"],[276,"impl-Debug-for-ApiError"],[277,"impl-Display-for-ApiError"],[401,"impl-Debug-for-AppError"],[402,"impl-Display-for-AppError"],[481,"impl-Display-for-ServerError"],[482,"impl-Debug-for-ServerError"],[484,"impl-From%3CConfigError%3E-for-ServerError"],[485,"impl-From%3CSocketError%3CE%3E%3E-for-ServerError"],[486,"impl-From%3CError%3E-for-ServerError"],[487,"impl-From%3CRequestError%3E-for-ServerError"],[560,"impl-Debug-for-Method"],[561,"impl-Display-for-Method"],[663,"impl-Display-for-RequestError"],[664,"impl-Debug-for-RequestError"],[667,"impl-Debug-for-RequestParamType"],[668,"impl-Display-for-RequestParamType"],[760,"impl-Debug-for-SocketError%3CE%3E"],[761,"impl-Display-for-SocketError%3CE%3E"],[763,"impl-From%3CRequestError%3E-for-SocketError%3CE%3E"],[764,"impl-From%3CError%3E-for-SocketError%3CE%3E"],[765,"impl-From%3CError%3E-for-SocketError%3CE%3E"],[767,"impl-From%3CError%3E-for-SocketError%3CE%3E"],[866,"impl-PartialEq-for-StatusCode"],[867,"impl-PartialEq%3CStatusCode%3E-for-StatusCode"],[868,"impl-PartialEq%3CStatusCode%3E-for-StatusCode"],[873,"impl-Debug-for-StatusCode"],[874,"impl-Display-for-StatusCode"],[875,"impl-Debug-for-OutOfRangeError"],[876,"impl-Display-for-OutOfRangeError"],[877,"impl-From%3CStatusCode%3E-for-StatusCode"],[879,"impl-From%3CStatusCode%3E-for-StatusCode"]]}]\
]'));
if (typeof exports !== 'undefined') exports.searchIndex = searchIndex;
else if (window.initSearch) window.initSearch(searchIndex);
diff --git a/settings.html b/settings.html
index 6fbfa6d7..b97e5f86 100644
--- a/settings.html
+++ b/settings.html
@@ -1,2 +1,2 @@
-1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +
use itertools::Itertools;
+use snafu::Snafu;
+use std::{
+ collections::{btree_map::Entry, BTreeMap},
+ ops::Index,
+};
+
+pub use crate::join;
+
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub(crate) struct Module<Api> {
+ pub(crate) prefix: Vec<String>,
+ pub(crate) versions: BTreeMap<u64, Api>,
+}
+
+impl<Api> Module<Api> {
+ fn new(prefix: Vec<String>) -> Self {
+ Self {
+ prefix,
+ versions: Default::default(),
+ }
+ }
+
+ pub(crate) fn path(&self) -> String {
+ self.prefix.join("/")
+ }
+}
+
+#[derive(Clone, Debug, Snafu, PartialEq, Eq)]
+pub enum DispatchError {
+ #[snafu(display("duplicate module {prefix} v{version}"))]
+ ModuleAlreadyExists { prefix: String, version: u64 },
+ #[snafu(display("module {prefix} cannot be a prefix of module {conflict}"))]
+ ConflictingModules { prefix: String, conflict: String },
+}
+
+/// Mapping from route prefixes to APIs.
+#[derive(Debug)]
+pub(crate) enum Trie<Api> {
+ Branch {
+ /// The route prefix represented by this node.
+ prefix: Vec<String>,
+ /// APIs with this prefix, indexed by the next route segment.
+ children: BTreeMap<String, Box<Self>>,
+ },
+ Leaf {
+ /// APIs available at this prefix, sorted by version.
+ module: Module<Api>,
+ },
+}
+
+impl<Api> Default for Trie<Api> {
+ fn default() -> Self {
+ Self::Branch {
+ prefix: vec![],
+ children: Default::default(),
+ }
+ }
+}
+
+impl<Api> Trie<Api> {
+ /// Whether this is a singleton [`Trie`].
+ ///
+ /// A singleton [`Trie`] is one with only one module, registered under the empty prefix. Note
+ /// that any [`Trie`] with a module with an empty prefix must be singleton, because no other
+ /// modules would be permitted: the empty prefix is a prefix of every other module path.
+ pub(crate) fn is_singleton(&self) -> bool {
+ matches!(self, Self::Leaf { .. })
+ }
+
+ /// Insert a new API with a certain version under the given prefix.
+ pub(crate) fn insert<I>(
+ &mut self,
+ prefix: I,
+ version: u64,
+ api: Api,
+ ) -> Result<(), DispatchError>
+ where
+ I: IntoIterator,
+ I::Item: Into<String>,
+ {
+ let mut prefix = prefix.into_iter().map(|segment| segment.into());
+
+ // Traverse to a leaf matching `prefix`.
+ let mut curr = self;
+ while let Some(segment) = prefix.next() {
+ // If there are more segments in the prefix, we must be at a branch.
+ match curr {
+ Self::Branch { prefix, children } => {
+ // Move to the child associated with the next path segment, inserting an empty
+ // child if this is the first module we've seen that has this path as a prefix.
+ curr = children.entry(segment.clone()).or_insert_with(|| {
+ let mut prefix = prefix.clone();
+ prefix.push(segment);
+ Box::new(Trie::Branch {
+ prefix,
+ children: Default::default(),
+ })
+ });
+ }
+ Self::Leaf { module } => {
+ // If there is a leaf here, then there is already a module registered which is a
+ // prefix of the new module. This is not allowed.
+ return Err(DispatchError::ConflictingModules {
+ prefix: module.path(),
+ conflict: join!(&module.path(), &segment, &prefix.join("/")),
+ });
+ }
+ }
+ }
+
+ // If we have reached the end of the prefix, we must be at either a leaf or a temporary
+ // empty branch that we can turn into a leaf.
+ if let Self::Branch { prefix, children } = curr {
+ if children.is_empty() {
+ *curr = Self::Leaf {
+ module: Module::new(prefix.clone()),
+ };
+ } else {
+ // If we have a non-trival branch at the end of the desired prefix, there is already
+ // a module registered for which `prefix` is a strict prefix of the registered path.
+ // This is not allowed. To give a useful error message, follow the existing trie
+ // down to a leaf so we can give an example of a module which conflicts with this
+ // prefix.
+ let prefix = prefix.join("/");
+ let conflict = loop {
+ match curr {
+ Self::Branch { children, .. } => {
+ curr = children
+ .values_mut()
+ .next()
+ .expect("malformed dispatch trie: empty branch");
+ }
+ Self::Leaf { module } => {
+ break module.path();
+ }
+ }
+ };
+ return Err(DispatchError::ConflictingModules { prefix, conflict });
+ }
+ }
+ let Self::Leaf { module } = curr else {
+ unreachable!();
+ };
+
+ // Insert the new API, as long as there isn't already an API with the same version in this
+ // module.
+ let Entry::Vacant(e) = module.versions.entry(version) else {
+ return Err(DispatchError::ModuleAlreadyExists {
+ prefix: module.path(),
+ version,
+ });
+ };
+ e.insert(api);
+ Ok(())
+ }
+
+ /// Get the module named by `prefix`.
+ ///
+ /// This function is similar to [`search`](Self::search), except the given `prefix` must exactly
+ /// match the prefix under which a module is registered.
+ pub(crate) fn get<I>(&self, prefix: I) -> Option<&Module<Api>>
+ where
+ I: IntoIterator,
+ I::Item: AsRef<str>,
+ {
+ let mut iter = prefix.into_iter();
+ let module = self.traverse(&mut iter)?;
+ // Check for exact match.
+ if iter.next().is_some() {
+ None
+ } else {
+ Some(module)
+ }
+ }
+
+ /// Get the supported versions of the API identified by the given request path.
+ ///
+ /// If a prefix of `path` uniquely identifies a registered module, the module (with all
+ /// supported versions) is returned.
+ pub(crate) fn search<I>(&self, path: I) -> Option<&Module<Api>>
+ where
+ I: IntoIterator,
+ I::Item: AsRef<str>,
+ {
+ self.traverse(&mut path.into_iter())
+ }
+
+ /// Iterate over registered modules and their supported versions.
+ pub(crate) fn iter(&self) -> Iter<Api> {
+ Iter { stack: vec![self] }
+ }
+
+ /// Internal implementation of `get` and `search`.
+ ///
+ /// Returns the matching module and advances the iterator past all the segments used in the
+ /// match.
+ fn traverse<I>(&self, iter: &mut I) -> Option<&Module<Api>>
+ where
+ I: Iterator,
+ I::Item: AsRef<str>,
+ {
+ let mut curr = self;
+ loop {
+ match curr {
+ Self::Branch { children, .. } => {
+ // Traverse to the next child based on the next segment in the path.
+ let segment = iter.next()?;
+ curr = children.get(segment.as_ref())?;
+ }
+ Self::Leaf { module } => return Some(module),
+ }
+ }
+ }
+}
+
+pub(crate) struct Iter<'a, Api> {
+ stack: Vec<&'a Trie<Api>>,
+}
+
+impl<'a, Api> Iterator for Iter<'a, Api> {
+ type Item = &'a Module<Api>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ loop {
+ match self.stack.pop()? {
+ Trie::Branch { children, .. } => {
+ // Push children onto the stack and start visiting them. We add them in reverse
+ // order so that we will visit the lexicographically first children first.
+ self.stack
+ .extend(children.values().rev().map(|boxed| &**boxed));
+ }
+ Trie::Leaf { module } => return Some(module),
+ }
+ }
+ }
+}
+
+impl<'a, Api> IntoIterator for &'a Trie<Api> {
+ type IntoIter = Iter<'a, Api>;
+ type Item = &'a Module<Api>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.iter()
+ }
+}
+
+impl<I, Api> Index<I> for Trie<Api>
+where
+ I: IntoIterator,
+ I::Item: AsRef<str>,
+{
+ type Output = Module<Api>;
+
+ fn index(&self, index: I) -> &Self::Output {
+ self.get(index).unwrap()
+ }
+}
+
+/// Split a path prefix into its segments.
+///
+/// Leading and trailing slashes are ignored. That is, `/prefix/` yields only the single segment
+/// `prefix`, with no preceding or following empty segments.
+pub(crate) fn split(s: &str) -> impl '_ + Iterator<Item = &str> {
+ s.split('/').filter(|seg| !seg.is_empty())
+}
+
+/// Join two path strings, ensuring there are no leading or trailing slashes.
+pub(crate) fn join(s1: &str, s2: &str) -> String {
+ let s1 = s1.strip_prefix('/').unwrap_or(s1);
+ let s1 = s1.strip_suffix('/').unwrap_or(s1);
+ let s2 = s2.strip_prefix('/').unwrap_or(s2);
+ let s2 = s2.strip_suffix('/').unwrap_or(s2);
+ if s1.is_empty() {
+ s2.to_string()
+ } else if s2.is_empty() {
+ s1.to_string()
+ } else {
+ format!("{s1}/{s2}")
+ }
+}
+
+#[macro_export]
+macro_rules! join {
+ () => { String::new() };
+ ($s:expr) => { $s };
+ ($head:expr$(, $($tail:expr),*)?) => {
+ $crate::dispatch::join($head, &$crate::join!($($($tail),*)?))
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn test_empty_trie() {
+ let t = Trie::<()>::default();
+ assert_eq!(t.iter().next(), None);
+ assert_eq!(t.get(["mod"]), None);
+ }
+
+ #[test]
+ fn test_branch_trie() {
+ let mut t = Trie::default();
+
+ let mod_a = Module {
+ prefix: vec!["mod".into(), "a".into()],
+ versions: [(0, 0)].into(),
+ };
+ let mod_b = Module {
+ prefix: vec!["mod".into(), "b".into()],
+ versions: [(1, 1)].into(),
+ };
+
+ t.insert(["mod", "a"], 0, 0).unwrap();
+ t.insert(["mod", "b"], 1, 1).unwrap();
+
+ assert_eq!(t.iter().collect::<Vec<_>>(), [&mod_a, &mod_b]);
+
+ assert_eq!(t.search(["mod", "a", "route"]), Some(&mod_a));
+ assert_eq!(t.get(["mod", "a"]), Some(&mod_a));
+ assert_eq!(t.get(["mod", "a", "route"]), None);
+
+ assert_eq!(t.search(["mod", "b", "route"]), Some(&mod_b));
+ assert_eq!(t.get(["mod", "b"]), Some(&mod_b));
+ assert_eq!(t.get(["mod", "b", "route"]), None);
+
+ // Cannot register a module which is a prefix or suffix of the already registered modules.
+ t.insert(["mod"], 0, 0).unwrap_err();
+ t.insert(Vec::<String>::new(), 0, 0).unwrap_err();
+ t.insert(["mod", "a", "b"], 0, 0).unwrap_err();
+ }
+
+ #[test]
+ fn test_null_prefix() {
+ let mut t = Trie::default();
+
+ let module = Module {
+ prefix: vec![],
+ versions: [(0, 0)].into(),
+ };
+ t.insert(Vec::<String>::new(), 0, 0).unwrap();
+
+ assert_eq!(t.iter().collect::<Vec<_>>(), [&module]);
+ assert_eq!(t.search(["anything"]), Some(&module));
+ assert_eq!(t.get(Vec::<String>::new()), Some(&module));
+ assert_eq!(t.get(["anything"]), None);
+
+ // Any other module has the null module as a prefix and is thus not allowed.
+ t.insert(["anything"], 1, 1).unwrap_err();
+ }
+}
+