1
0
mirror of https://github.com/actix/actix-extras.git synced 2025-09-02 04:56:38 +02:00

Deploying to gh-pages from @ 1e682e7a59 🚀

This commit is contained in:
robjtede
2022-08-24 17:10:06 +00:00
parent 677c856277
commit a717748964
200 changed files with 8532 additions and 8481 deletions

View File

@@ -331,338 +331,342 @@
<span id="331">331</span>
<span id="332">332</span>
<span id="333">333</span>
</pre><pre class="rust"><code><span class="doccomment">//! Protobuf payload extractor for Actix Web.</span>
<span id="334">334</span>
<span id="335">335</span>
</pre><pre class="rust"><code><span class="doccomment">//! Protobuf payload extractor for Actix Web.
<span class="attribute">#![<span class="ident">forbid</span>(<span class="ident">unsafe_code</span>)]</span>
<span class="attribute">#![<span class="ident">deny</span>(<span class="ident">rust_2018_idioms</span>, <span class="ident">nonstandard_style</span>)]</span>
<span class="attribute">#![<span class="ident">warn</span>(<span class="ident">future_incompatible</span>)]</span>
</span><span class="attribute">#![forbid(unsafe_code)]
#![deny(rust_2018_idioms, nonstandard_style)]
#![warn(future_incompatible)]
<span class="kw">use</span> <span class="ident">std</span>::{
<span class="ident">fmt</span>,
<span class="ident">future::Future</span>,
<span class="ident">ops</span>::{<span class="ident">Deref</span>, <span class="ident">DerefMut</span>},
<span class="ident">pin::Pin</span>,
<span class="ident">task</span>::{<span class="self">self</span>, <span class="ident">Poll</span>},
</span><span class="kw">use </span>std::{
fmt,
future::Future,
ops::{Deref, DerefMut},
pin::Pin,
task::{<span class="self">self</span>, Poll},
};
<span class="kw">use</span> <span class="ident">actix_web</span>::{
<span class="ident">body::BoxBody</span>,
<span class="ident">dev::Payload</span>,
<span class="ident">error::PayloadError</span>,
<span class="ident">http::header</span>::{<span class="ident">CONTENT_LENGTH</span>, <span class="ident">CONTENT_TYPE</span>},
<span class="ident">web::BytesMut</span>,
<span class="ident">Error</span>, <span class="ident">FromRequest</span>, <span class="ident">HttpMessage</span>, <span class="ident">HttpRequest</span>, <span class="ident">HttpResponse</span>, <span class="ident">HttpResponseBuilder</span>, <span class="ident">Responder</span>,
<span class="ident">ResponseError</span>,
<span class="kw">use </span>actix_web::{
body::BoxBody,
dev::Payload,
error::PayloadError,
http::header::{CONTENT_LENGTH, CONTENT_TYPE},
web::BytesMut,
Error, FromRequest, HttpMessage, HttpRequest, HttpResponse, HttpResponseBuilder, Responder,
ResponseError,
};
<span class="kw">use</span> <span class="ident">derive_more::Display</span>;
<span class="kw">use</span> <span class="ident">futures_util</span>::{
<span class="ident">future</span>::{<span class="ident">FutureExt</span> <span class="kw">as</span> <span class="kw">_</span>, <span class="ident">LocalBoxFuture</span>},
<span class="ident">stream::StreamExt</span> <span class="kw">as</span> <span class="kw">_</span>,
<span class="kw">use </span>derive_more::Display;
<span class="kw">use </span>futures_util::{
future::{FutureExt <span class="kw">as _</span>, LocalBoxFuture},
stream::StreamExt <span class="kw">as _</span>,
};
<span class="kw">use</span> <span class="ident">prost</span>::{<span class="ident">DecodeError</span> <span class="kw">as</span> <span class="ident">ProtoBufDecodeError</span>, <span class="ident">EncodeError</span> <span class="kw">as</span> <span class="ident">ProtoBufEncodeError</span>, <span class="ident">Message</span>};
<span class="kw">use </span>prost::{DecodeError <span class="kw">as </span>ProtoBufDecodeError, EncodeError <span class="kw">as </span>ProtoBufEncodeError, Message};
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Display</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">ProtoBufPayloadError</span> {
<span class="doccomment">/// Payload size is bigger than 256k</span>
<span class="attribute">#[<span class="ident">display</span>(<span class="ident">fmt</span> <span class="op">=</span> <span class="string">&quot;Payload size is bigger than 256k&quot;</span>)]</span>
<span class="ident">Overflow</span>,
<span class="attribute">#[derive(Debug, Display)]
</span><span class="kw">pub enum </span>ProtoBufPayloadError {
<span class="doccomment">/// Payload size is bigger than 256k
</span><span class="attribute">#[display(fmt = <span class="string">&quot;Payload size is bigger than 256k&quot;</span>)]
</span>Overflow,
<span class="doccomment">/// Content type error</span>
<span class="attribute">#[<span class="ident">display</span>(<span class="ident">fmt</span> <span class="op">=</span> <span class="string">&quot;Content type error&quot;</span>)]</span>
<span class="ident">ContentType</span>,
<span class="doccomment">/// Content type error
</span><span class="attribute">#[display(fmt = <span class="string">&quot;Content type error&quot;</span>)]
</span>ContentType,
<span class="doccomment">/// Serialize error</span>
<span class="attribute">#[<span class="ident">display</span>(<span class="ident">fmt</span> <span class="op">=</span> <span class="string">&quot;ProtoBuf serialize error: {}&quot;</span>, <span class="ident">_0</span>)]</span>
<span class="ident">Serialize</span>(<span class="ident">ProtoBufEncodeError</span>),
<span class="doccomment">/// Serialize error
</span><span class="attribute">#[display(fmt = <span class="string">&quot;ProtoBuf serialize error: {}&quot;</span>, _0)]
</span>Serialize(ProtoBufEncodeError),
<span class="doccomment">/// Deserialize error</span>
<span class="attribute">#[<span class="ident">display</span>(<span class="ident">fmt</span> <span class="op">=</span> <span class="string">&quot;ProtoBuf deserialize error: {}&quot;</span>, <span class="ident">_0</span>)]</span>
<span class="ident">Deserialize</span>(<span class="ident">ProtoBufDecodeError</span>),
<span class="doccomment">/// Deserialize error
</span><span class="attribute">#[display(fmt = <span class="string">&quot;ProtoBuf deserialize error: {}&quot;</span>, _0)]
</span>Deserialize(ProtoBufDecodeError),
<span class="doccomment">/// Payload error</span>
<span class="attribute">#[<span class="ident">display</span>(<span class="ident">fmt</span> <span class="op">=</span> <span class="string">&quot;Error that occur during reading payload: {}&quot;</span>, <span class="ident">_0</span>)]</span>
<span class="ident">Payload</span>(<span class="ident">PayloadError</span>),
<span class="doccomment">/// Payload error
</span><span class="attribute">#[display(fmt = <span class="string">&quot;Error that occur during reading payload: {}&quot;</span>, _0)]
</span>Payload(PayloadError),
}
<span class="kw">impl</span> <span class="ident">ResponseError</span> <span class="kw">for</span> <span class="ident">ProtoBufPayloadError</span> {
<span class="kw">fn</span> <span class="ident">error_response</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="ident">HttpResponse</span> {
<span class="kw">match</span> <span class="kw-2">*</span><span class="self">self</span> {
<span class="ident">ProtoBufPayloadError::Overflow</span> =&gt; <span class="ident">HttpResponse::PayloadTooLarge</span>().<span class="ident">into</span>(),
<span class="kw">_</span> =&gt; <span class="ident">HttpResponse::BadRequest</span>().<span class="ident">into</span>(),
<span class="kw">impl </span>ResponseError <span class="kw">for </span>ProtoBufPayloadError {
<span class="kw">fn </span>error_response(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; HttpResponse {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
ProtoBufPayloadError::Overflow =&gt; HttpResponse::PayloadTooLarge().into(),
<span class="kw">_ </span>=&gt; HttpResponse::BadRequest().into(),
}
}
}
<span class="kw">impl</span> <span class="ident">From</span><span class="op">&lt;</span><span class="ident">PayloadError</span><span class="op">&gt;</span> <span class="kw">for</span> <span class="ident">ProtoBufPayloadError</span> {
<span class="kw">fn</span> <span class="ident">from</span>(<span class="ident">err</span>: <span class="ident">PayloadError</span>) -&gt; <span class="ident">ProtoBufPayloadError</span> {
<span class="ident">ProtoBufPayloadError::Payload</span>(<span class="ident">err</span>)
<span class="kw">impl </span>From&lt;PayloadError&gt; <span class="kw">for </span>ProtoBufPayloadError {
<span class="kw">fn </span>from(err: PayloadError) -&gt; ProtoBufPayloadError {
ProtoBufPayloadError::Payload(err)
}
}
<span class="kw">impl</span> <span class="ident">From</span><span class="op">&lt;</span><span class="ident">ProtoBufDecodeError</span><span class="op">&gt;</span> <span class="kw">for</span> <span class="ident">ProtoBufPayloadError</span> {
<span class="kw">fn</span> <span class="ident">from</span>(<span class="ident">err</span>: <span class="ident">ProtoBufDecodeError</span>) -&gt; <span class="ident">ProtoBufPayloadError</span> {
<span class="ident">ProtoBufPayloadError::Deserialize</span>(<span class="ident">err</span>)
<span class="kw">impl </span>From&lt;ProtoBufDecodeError&gt; <span class="kw">for </span>ProtoBufPayloadError {
<span class="kw">fn </span>from(err: ProtoBufDecodeError) -&gt; ProtoBufPayloadError {
ProtoBufPayloadError::Deserialize(err)
}
}
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">ProtoBuf</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Message</span><span class="op">&gt;</span>(<span class="kw">pub</span> <span class="ident">T</span>);
<span class="kw">pub struct </span>ProtoBuf&lt;T: Message&gt;(<span class="kw">pub </span>T);
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Message</span><span class="op">&gt;</span> <span class="ident">Deref</span> <span class="kw">for</span> <span class="ident">ProtoBuf</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">type</span> <span class="ident">Target</span> <span class="op">=</span> <span class="ident">T</span>;
<span class="kw">impl</span>&lt;T: Message&gt; Deref <span class="kw">for </span>ProtoBuf&lt;T&gt; {
<span class="kw">type </span>Target = T;
<span class="kw">fn</span> <span class="ident">deref</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span><span class="ident">T</span> {
<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="number">0</span>
}
<span class="kw">fn </span>deref(<span class="kw-2">&amp;</span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;</span>T {
<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="number">0
</span>}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Message</span><span class="op">&gt;</span> <span class="ident">DerefMut</span> <span class="kw">for</span> <span class="ident">ProtoBuf</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">deref_mut</span>(<span class="kw-2">&amp;mut</span> <span class="self">self</span>) -&gt; <span class="kw-2">&amp;mut</span> <span class="ident">T</span> {
<span class="kw-2">&amp;mut</span> <span class="self">self</span>.<span class="number">0</span>
}
<span class="kw">impl</span>&lt;T: Message&gt; DerefMut <span class="kw">for </span>ProtoBuf&lt;T&gt; {
<span class="kw">fn </span>deref_mut(<span class="kw-2">&amp;mut </span><span class="self">self</span>) -&gt; <span class="kw-2">&amp;mut </span>T {
<span class="kw-2">&amp;mut </span><span class="self">self</span>.<span class="number">0
</span>}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Message</span><span class="op">&gt;</span> <span class="ident">fmt::Debug</span> <span class="kw">for</span> <span class="ident">ProtoBuf</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">T</span>: <span class="ident">fmt::Debug</span>,
<span class="kw">impl</span>&lt;T: Message&gt; fmt::Debug <span class="kw">for </span>ProtoBuf&lt;T&gt;
<span class="kw">where
</span>T: fmt::Debug,
{
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;mut</span> <span class="ident">fmt::Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) -&gt; <span class="ident">fmt::Result</span> {
<span class="macro">write!</span>(<span class="ident">f</span>, <span class="string">&quot;ProtoBuf: {:?}&quot;</span>, <span class="self">self</span>.<span class="number">0</span>)
<span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">&#39;_</span>&gt;) -&gt; fmt::Result {
<span class="macro">write!</span>(f, <span class="string">&quot;ProtoBuf: {:?}&quot;</span>, <span class="self">self</span>.<span class="number">0</span>)
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Message</span><span class="op">&gt;</span> <span class="ident">fmt::Display</span> <span class="kw">for</span> <span class="ident">ProtoBuf</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">T</span>: <span class="ident">fmt::Display</span>,
<span class="kw">impl</span>&lt;T: Message&gt; fmt::Display <span class="kw">for </span>ProtoBuf&lt;T&gt;
<span class="kw">where
</span>T: fmt::Display,
{
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;mut</span> <span class="ident">fmt::Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) -&gt; <span class="ident">fmt::Result</span> {
<span class="ident">fmt::Display::fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="number">0</span>, <span class="ident">f</span>)
<span class="kw">fn </span>fmt(<span class="kw-2">&amp;</span><span class="self">self</span>, f: <span class="kw-2">&amp;mut </span>fmt::Formatter&lt;<span class="lifetime">&#39;_</span>&gt;) -&gt; fmt::Result {
fmt::Display::fmt(<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="number">0</span>, f)
}
}
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">ProtoBufConfig</span> {
<span class="ident">limit</span>: <span class="ident">usize</span>,
<span class="kw">pub struct </span>ProtoBufConfig {
limit: usize,
}
<span class="kw">impl</span> <span class="ident">ProtoBufConfig</span> {
<span class="doccomment">/// Change max size of payload. By default max size is 256Kb</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">limit</span>(<span class="kw-2">&amp;mut</span> <span class="self">self</span>, <span class="ident">limit</span>: <span class="ident">usize</span>) -&gt; <span class="kw-2">&amp;mut</span> <span class="self">Self</span> {
<span class="self">self</span>.<span class="ident">limit</span> <span class="op">=</span> <span class="ident">limit</span>;
<span class="self">self</span>
<span class="kw">impl </span>ProtoBufConfig {
<span class="doccomment">/// Change max size of payload. By default max size is 256Kb
</span><span class="kw">pub fn </span>limit(<span class="kw-2">&amp;mut </span><span class="self">self</span>, limit: usize) -&gt; <span class="kw-2">&amp;mut </span><span class="self">Self </span>{
<span class="self">self</span>.limit = limit;
<span class="self">self
</span>}
}
<span class="kw">impl </span>Default <span class="kw">for </span>ProtoBufConfig {
<span class="kw">fn </span>default() -&gt; <span class="self">Self </span>{
ProtoBufConfig { limit: <span class="number">262_144 </span>}
}
}
<span class="kw">impl</span> <span class="ident">Default</span> <span class="kw">for</span> <span class="ident">ProtoBufConfig</span> {
<span class="kw">fn</span> <span class="ident">default</span>() -&gt; <span class="self">Self</span> {
<span class="ident">ProtoBufConfig</span> { <span class="ident">limit</span>: <span class="number">262_144</span> }
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">FromRequest</span> <span class="kw">for</span> <span class="ident">ProtoBuf</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">T</span>: <span class="ident">Message</span> <span class="op">+</span> <span class="ident">Default</span> <span class="op">+</span> <span class="lifetime">&#39;static</span>,
<span class="kw">impl</span>&lt;T&gt; FromRequest <span class="kw">for </span>ProtoBuf&lt;T&gt;
<span class="kw">where
</span>T: Message + Default + <span class="lifetime">&#39;static</span>,
{
<span class="kw">type</span> <span class="ident">Error</span> <span class="op">=</span> <span class="ident">Error</span>;
<span class="kw">type</span> <span class="ident">Future</span> <span class="op">=</span> <span class="ident">LocalBoxFuture</span><span class="op">&lt;</span><span class="lifetime">&#39;static</span>, <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="self">Self</span>, <span class="ident">Error</span><span class="op">&gt;</span><span class="op">&gt;</span>;
<span class="kw">type </span>Error = Error;
<span class="kw">type </span>Future = LocalBoxFuture&lt;<span class="lifetime">&#39;static</span>, <span class="prelude-ty">Result</span>&lt;<span class="self">Self</span>, Error&gt;&gt;;
<span class="attribute">#[<span class="ident">inline</span>]</span>
<span class="kw">fn</span> <span class="ident">from_request</span>(<span class="ident">req</span>: <span class="kw-2">&amp;</span><span class="ident">HttpRequest</span>, <span class="ident">payload</span>: <span class="kw-2">&amp;mut</span> <span class="ident">Payload</span>) -&gt; <span class="ident"><span class="self">Self</span>::Future</span> {
<span class="kw">let</span> <span class="ident">limit</span> <span class="op">=</span> <span class="ident">req</span>
.<span class="ident">app_data</span>::<span class="op">&lt;</span><span class="ident">ProtoBufConfig</span><span class="op">&gt;</span>()
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">c</span><span class="op">|</span> <span class="ident">c</span>.<span class="ident">limit</span>)
.<span class="ident">unwrap_or</span>(<span class="number">262_144</span>);
<span class="ident">ProtoBufMessage::new</span>(<span class="ident">req</span>, <span class="ident">payload</span>)
.<span class="ident">limit</span>(<span class="ident">limit</span>)
.<span class="ident">map</span>(<span class="kw">move</span> <span class="op">|</span><span class="ident">res</span><span class="op">|</span> <span class="kw">match</span> <span class="ident">res</span> {
<span class="prelude-val">Err</span>(<span class="ident">e</span>) =&gt; <span class="prelude-val">Err</span>(<span class="ident">e</span>.<span class="ident">into</span>()),
<span class="prelude-val">Ok</span>(<span class="ident">item</span>) =&gt; <span class="prelude-val">Ok</span>(<span class="ident">ProtoBuf</span>(<span class="ident">item</span>)),
<span class="attribute">#[inline]
</span><span class="kw">fn </span>from_request(req: <span class="kw-2">&amp;</span>HttpRequest, payload: <span class="kw-2">&amp;mut </span>Payload) -&gt; <span class="self">Self</span>::Future {
<span class="kw">let </span>limit = req
.app_data::&lt;ProtoBufConfig&gt;()
.map(|c| c.limit)
.unwrap_or(<span class="number">262_144</span>);
ProtoBufMessage::new(req, payload)
.limit(limit)
.map(<span class="kw">move </span>|res| <span class="kw">match </span>res {
<span class="prelude-val">Err</span>(e) =&gt; <span class="prelude-val">Err</span>(e.into()),
<span class="prelude-val">Ok</span>(item) =&gt; <span class="prelude-val">Ok</span>(ProtoBuf(item)),
})
.<span class="ident">boxed_local</span>()
.boxed_local()
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Message</span> <span class="op">+</span> <span class="ident">Default</span><span class="op">&gt;</span> <span class="ident">Responder</span> <span class="kw">for</span> <span class="ident">ProtoBuf</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">type</span> <span class="ident">Body</span> <span class="op">=</span> <span class="ident">BoxBody</span>;
<span class="kw">impl</span>&lt;T: Message + Default&gt; Responder <span class="kw">for </span>ProtoBuf&lt;T&gt; {
<span class="kw">type </span>Body = BoxBody;
<span class="kw">fn</span> <span class="ident">respond_to</span>(<span class="self">self</span>, <span class="kw">_</span>: <span class="kw-2">&amp;</span><span class="ident">HttpRequest</span>) -&gt; <span class="ident">HttpResponse</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">buf</span> <span class="op">=</span> <span class="ident">Vec::new</span>();
<span class="kw">match</span> <span class="self">self</span>.<span class="number">0</span>.<span class="ident">encode</span>(<span class="kw-2">&amp;mut</span> <span class="ident">buf</span>) {
<span class="prelude-val">Ok</span>(()) =&gt; <span class="ident">HttpResponse::Ok</span>()
.<span class="ident">content_type</span>(<span class="string">&quot;application/protobuf&quot;</span>)
.<span class="ident">body</span>(<span class="ident">buf</span>),
<span class="prelude-val">Err</span>(<span class="ident">err</span>) =&gt; <span class="ident">HttpResponse::from_error</span>(<span class="ident">Error::from</span>(<span class="ident">ProtoBufPayloadError::Serialize</span>(<span class="ident">err</span>))),
<span class="kw">fn </span>respond_to(<span class="self">self</span>, <span class="kw">_</span>: <span class="kw-2">&amp;</span>HttpRequest) -&gt; HttpResponse {
<span class="kw">let </span><span class="kw-2">mut </span>buf = Vec::new();
<span class="kw">match </span><span class="self">self</span>.<span class="number">0</span>.encode(<span class="kw-2">&amp;mut </span>buf) {
<span class="prelude-val">Ok</span>(()) =&gt; HttpResponse::Ok()
.content_type(<span class="string">&quot;application/protobuf&quot;</span>)
.body(buf),
<span class="prelude-val">Err</span>(err) =&gt; HttpResponse::from_error(Error::from(ProtoBufPayloadError::Serialize(err))),
}
}
}
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">ProtoBufMessage</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Message</span> <span class="op">+</span> <span class="ident">Default</span><span class="op">&gt;</span> {
<span class="ident">limit</span>: <span class="ident">usize</span>,
<span class="ident">length</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">usize</span><span class="op">&gt;</span>,
<span class="ident">stream</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">Payload</span><span class="op">&gt;</span>,
<span class="ident">err</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">ProtoBufPayloadError</span><span class="op">&gt;</span>,
<span class="ident">fut</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">LocalBoxFuture</span><span class="op">&lt;</span><span class="lifetime">&#39;static</span>, <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">ProtoBufPayloadError</span><span class="op">&gt;</span><span class="op">&gt;</span><span class="op">&gt;</span>,
<span class="kw">pub struct </span>ProtoBufMessage&lt;T: Message + Default&gt; {
limit: usize,
length: <span class="prelude-ty">Option</span>&lt;usize&gt;,
stream: <span class="prelude-ty">Option</span>&lt;Payload&gt;,
err: <span class="prelude-ty">Option</span>&lt;ProtoBufPayloadError&gt;,
fut: <span class="prelude-ty">Option</span>&lt;LocalBoxFuture&lt;<span class="lifetime">&#39;static</span>, <span class="prelude-ty">Result</span>&lt;T, ProtoBufPayloadError&gt;&gt;&gt;,
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Message</span> <span class="op">+</span> <span class="ident">Default</span><span class="op">&gt;</span> <span class="ident">ProtoBufMessage</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="doccomment">/// Create `ProtoBufMessage` for request.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">new</span>(<span class="ident">req</span>: <span class="kw-2">&amp;</span><span class="ident">HttpRequest</span>, <span class="ident">payload</span>: <span class="kw-2">&amp;mut</span> <span class="ident">Payload</span>) -&gt; <span class="self">Self</span> {
<span class="kw">if</span> <span class="ident">req</span>.<span class="ident">content_type</span>() <span class="op">!</span><span class="op">=</span> <span class="string">&quot;application/protobuf&quot;</span> {
<span class="kw">return</span> <span class="ident">ProtoBufMessage</span> {
<span class="ident">limit</span>: <span class="number">262_144</span>,
<span class="ident">length</span>: <span class="prelude-val">None</span>,
<span class="ident">stream</span>: <span class="prelude-val">None</span>,
<span class="ident">fut</span>: <span class="prelude-val">None</span>,
<span class="ident">err</span>: <span class="prelude-val">Some</span>(<span class="ident">ProtoBufPayloadError::ContentType</span>),
<span class="kw">impl</span>&lt;T: Message + Default&gt; ProtoBufMessage&lt;T&gt; {
<span class="doccomment">/// Create `ProtoBufMessage` for request.
</span><span class="kw">pub fn </span>new(req: <span class="kw-2">&amp;</span>HttpRequest, payload: <span class="kw-2">&amp;mut </span>Payload) -&gt; <span class="self">Self </span>{
<span class="kw">if </span>req.content_type() != <span class="string">&quot;application/protobuf&quot;
</span>&amp;&amp; req.content_type() != <span class="string">&quot;application/x-protobuf&quot;
</span>{
<span class="kw">return </span>ProtoBufMessage {
limit: <span class="number">262_144</span>,
length: <span class="prelude-val">None</span>,
stream: <span class="prelude-val">None</span>,
fut: <span class="prelude-val">None</span>,
err: <span class="prelude-val">Some</span>(ProtoBufPayloadError::ContentType),
};
}
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">len</span> <span class="op">=</span> <span class="prelude-val">None</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">l</span>) <span class="op">=</span> <span class="ident">req</span>.<span class="ident">headers</span>().<span class="ident">get</span>(<span class="ident">CONTENT_LENGTH</span>) {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Ok</span>(<span class="ident">s</span>) <span class="op">=</span> <span class="ident">l</span>.<span class="ident">to_str</span>() {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Ok</span>(<span class="ident">l</span>) <span class="op">=</span> <span class="ident">s</span>.<span class="ident">parse</span>::<span class="op">&lt;</span><span class="ident">usize</span><span class="op">&gt;</span>() {
<span class="ident">len</span> <span class="op">=</span> <span class="prelude-val">Some</span>(<span class="ident">l</span>)
<span class="kw">let </span><span class="kw-2">mut </span>len = <span class="prelude-val">None</span>;
<span class="kw">if let </span><span class="prelude-val">Some</span>(l) = req.headers().get(CONTENT_LENGTH) {
<span class="kw">if let </span><span class="prelude-val">Ok</span>(s) = l.to_str() {
<span class="kw">if let </span><span class="prelude-val">Ok</span>(l) = s.parse::&lt;usize&gt;() {
len = <span class="prelude-val">Some</span>(l)
}
}
}
<span class="ident">ProtoBufMessage</span> {
<span class="ident">limit</span>: <span class="number">262_144</span>,
<span class="ident">length</span>: <span class="ident">len</span>,
<span class="ident">stream</span>: <span class="prelude-val">Some</span>(<span class="ident">payload</span>.<span class="ident">take</span>()),
<span class="ident">fut</span>: <span class="prelude-val">None</span>,
<span class="ident">err</span>: <span class="prelude-val">None</span>,
ProtoBufMessage {
limit: <span class="number">262_144</span>,
length: len,
stream: <span class="prelude-val">Some</span>(payload.take()),
fut: <span class="prelude-val">None</span>,
err: <span class="prelude-val">None</span>,
}
}
<span class="doccomment">/// Change max size of payload. By default max size is 256Kb</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">limit</span>(<span class="kw-2">mut</span> <span class="self">self</span>, <span class="ident">limit</span>: <span class="ident">usize</span>) -&gt; <span class="self">Self</span> {
<span class="self">self</span>.<span class="ident">limit</span> <span class="op">=</span> <span class="ident">limit</span>;
<span class="self">self</span>
}
<span class="doccomment">/// Change max size of payload. By default max size is 256Kb
</span><span class="kw">pub fn </span>limit(<span class="kw-2">mut </span><span class="self">self</span>, limit: usize) -&gt; <span class="self">Self </span>{
<span class="self">self</span>.limit = limit;
<span class="self">self
</span>}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Message</span> <span class="op">+</span> <span class="ident">Default</span> <span class="op">+</span> <span class="lifetime">&#39;static</span><span class="op">&gt;</span> <span class="ident">Future</span> <span class="kw">for</span> <span class="ident">ProtoBufMessage</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">type</span> <span class="ident">Output</span> <span class="op">=</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">ProtoBufPayloadError</span><span class="op">&gt;</span>;
<span class="kw">impl</span>&lt;T: Message + Default + <span class="lifetime">&#39;static</span>&gt; Future <span class="kw">for </span>ProtoBufMessage&lt;T&gt; {
<span class="kw">type </span>Output = <span class="prelude-ty">Result</span>&lt;T, ProtoBufPayloadError&gt;;
<span class="kw">fn</span> <span class="ident">poll</span>(<span class="kw-2">mut</span> <span class="self">self</span>: <span class="ident">Pin</span><span class="op">&lt;</span><span class="kw-2">&amp;mut</span> <span class="self">Self</span><span class="op">&gt;</span>, <span class="ident">task</span>: <span class="kw-2">&amp;mut</span> <span class="ident">task::Context</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) -&gt; <span class="ident">Poll</span><span class="op">&lt;</span><span class="ident"><span class="self">Self</span>::Output</span><span class="op">&gt;</span> {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="kw-2">ref</span> <span class="kw-2">mut</span> <span class="ident">fut</span>) <span class="op">=</span> <span class="self">self</span>.<span class="ident">fut</span> {
<span class="kw">return</span> <span class="ident">Pin::new</span>(<span class="ident">fut</span>).<span class="ident">poll</span>(<span class="ident">task</span>);
<span class="kw">fn </span>poll(<span class="kw-2">mut </span><span class="self">self</span>: Pin&lt;<span class="kw-2">&amp;mut </span><span class="self">Self</span>&gt;, task: <span class="kw-2">&amp;mut </span>task::Context&lt;<span class="lifetime">&#39;_</span>&gt;) -&gt; Poll&lt;<span class="self">Self</span>::Output&gt; {
<span class="kw">if let </span><span class="prelude-val">Some</span>(<span class="kw-2">ref mut </span>fut) = <span class="self">self</span>.fut {
<span class="kw">return </span>Pin::new(fut).poll(task);
}
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">err</span>) <span class="op">=</span> <span class="self">self</span>.<span class="ident">err</span>.<span class="ident">take</span>() {
<span class="kw">return</span> <span class="ident">Poll::Ready</span>(<span class="prelude-val">Err</span>(<span class="ident">err</span>));
<span class="kw">if let </span><span class="prelude-val">Some</span>(err) = <span class="self">self</span>.err.take() {
<span class="kw">return </span>Poll::Ready(<span class="prelude-val">Err</span>(err));
}
<span class="kw">let</span> <span class="ident">limit</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">limit</span>;
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">len</span>) <span class="op">=</span> <span class="self">self</span>.<span class="ident">length</span>.<span class="ident">take</span>() {
<span class="kw">if</span> <span class="ident">len</span> <span class="op">&gt;</span> <span class="ident">limit</span> {
<span class="kw">return</span> <span class="ident">Poll::Ready</span>(<span class="prelude-val">Err</span>(<span class="ident">ProtoBufPayloadError::Overflow</span>));
<span class="kw">let </span>limit = <span class="self">self</span>.limit;
<span class="kw">if let </span><span class="prelude-val">Some</span>(len) = <span class="self">self</span>.length.take() {
<span class="kw">if </span>len &gt; limit {
<span class="kw">return </span>Poll::Ready(<span class="prelude-val">Err</span>(ProtoBufPayloadError::Overflow));
}
}
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">stream</span> <span class="op">=</span> <span class="self">self</span>
.<span class="ident">stream</span>
.<span class="ident">take</span>()
.<span class="ident">expect</span>(<span class="string">&quot;ProtoBufMessage could not be used second time&quot;</span>);
<span class="kw">let </span><span class="kw-2">mut </span>stream = <span class="self">self
</span>.stream
.take()
.expect(<span class="string">&quot;ProtoBufMessage could not be used second time&quot;</span>);
<span class="self">self</span>.<span class="ident">fut</span> <span class="op">=</span> <span class="prelude-val">Some</span>(
<span class="kw">async</span> <span class="kw">move</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">body</span> <span class="op">=</span> <span class="ident">BytesMut::with_capacity</span>(<span class="number">8192</span>);
<span class="self">self</span>.fut = <span class="prelude-val">Some</span>(
<span class="kw">async move </span>{
<span class="kw">let </span><span class="kw-2">mut </span>body = BytesMut::with_capacity(<span class="number">8192</span>);
<span class="kw">while</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">item</span>) <span class="op">=</span> <span class="ident">stream</span>.<span class="ident">next</span>().<span class="kw">await</span> {
<span class="kw">let</span> <span class="ident">chunk</span> <span class="op">=</span> <span class="ident">item</span><span class="question-mark">?</span>;
<span class="kw">if</span> (<span class="ident">body</span>.<span class="ident">len</span>() <span class="op">+</span> <span class="ident">chunk</span>.<span class="ident">len</span>()) <span class="op">&gt;</span> <span class="ident">limit</span> {
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">ProtoBufPayloadError::Overflow</span>);
} <span class="kw">else</span> {
<span class="ident">body</span>.<span class="ident">extend_from_slice</span>(<span class="kw-2">&amp;</span><span class="ident">chunk</span>);
<span class="kw">while let </span><span class="prelude-val">Some</span>(item) = stream.next().<span class="kw">await </span>{
<span class="kw">let </span>chunk = item<span class="question-mark">?</span>;
<span class="kw">if </span>(body.len() + chunk.len()) &gt; limit {
<span class="kw">return </span><span class="prelude-val">Err</span>(ProtoBufPayloadError::Overflow);
} <span class="kw">else </span>{
body.extend_from_slice(<span class="kw-2">&amp;</span>chunk);
}
}
<span class="prelude-val">Ok</span>(<span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span><span class="ident">::decode</span>(<span class="kw-2">&amp;mut</span> <span class="ident">body</span>)<span class="question-mark">?</span>)
<span class="prelude-val">Ok</span>(&lt;T&gt;::decode(<span class="kw-2">&amp;mut </span>body)<span class="question-mark">?</span>)
}
.<span class="ident">boxed_local</span>(),
.boxed_local(),
);
<span class="self">self</span>.<span class="ident">poll</span>(<span class="ident">task</span>)
<span class="self">self</span>.poll(task)
}
}
<span class="kw">pub</span> <span class="kw">trait</span> <span class="ident">ProtoBufResponseBuilder</span> {
<span class="kw">fn</span> <span class="ident">protobuf</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Message</span><span class="op">&gt;</span>(<span class="kw-2">&amp;mut</span> <span class="self">self</span>, <span class="ident">value</span>: <span class="ident">T</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">HttpResponse</span>, <span class="ident">Error</span><span class="op">&gt;</span>;
<span class="kw">pub trait </span>ProtoBufResponseBuilder {
<span class="kw">fn </span>protobuf&lt;T: Message&gt;(<span class="kw-2">&amp;mut </span><span class="self">self</span>, value: T) -&gt; <span class="prelude-ty">Result</span>&lt;HttpResponse, Error&gt;;
}
<span class="kw">impl</span> <span class="ident">ProtoBufResponseBuilder</span> <span class="kw">for</span> <span class="ident">HttpResponseBuilder</span> {
<span class="kw">fn</span> <span class="ident">protobuf</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">Message</span><span class="op">&gt;</span>(<span class="kw-2">&amp;mut</span> <span class="self">self</span>, <span class="ident">value</span>: <span class="ident">T</span>) -&gt; <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">HttpResponse</span>, <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="self">self</span>.<span class="ident">insert_header</span>((<span class="ident">CONTENT_TYPE</span>, <span class="string">&quot;application/protobuf&quot;</span>));
<span class="kw">impl </span>ProtoBufResponseBuilder <span class="kw">for </span>HttpResponseBuilder {
<span class="kw">fn </span>protobuf&lt;T: Message&gt;(<span class="kw-2">&amp;mut </span><span class="self">self</span>, value: T) -&gt; <span class="prelude-ty">Result</span>&lt;HttpResponse, Error&gt; {
<span class="self">self</span>.insert_header((CONTENT_TYPE, <span class="string">&quot;application/protobuf&quot;</span>));
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">body</span> <span class="op">=</span> <span class="ident">Vec::new</span>();
<span class="ident">value</span>
.<span class="ident">encode</span>(<span class="kw-2">&amp;mut</span> <span class="ident">body</span>)
.<span class="ident">map_err</span>(<span class="ident">ProtoBufPayloadError::Serialize</span>)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="self">self</span>.<span class="ident">body</span>(<span class="ident">body</span>))
<span class="kw">let </span><span class="kw-2">mut </span>body = Vec::new();
value
.encode(<span class="kw-2">&amp;mut </span>body)
.map_err(ProtoBufPayloadError::Serialize)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="self">self</span>.body(body))
}
}
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">test</span>)]</span>
<span class="kw">mod</span> <span class="ident">tests</span> {
<span class="kw">use</span> <span class="ident">actix_web::http::header</span>;
<span class="kw">use</span> <span class="ident">actix_web::test::TestRequest</span>;
<span class="attribute">#[cfg(test)]
</span><span class="kw">mod </span>tests {
<span class="kw">use </span>actix_web::http::header;
<span class="kw">use </span>actix_web::test::TestRequest;
<span class="kw">use</span> <span class="kw">super</span>::<span class="kw-2">*</span>;
<span class="kw">use super</span>::<span class="kw-2">*</span>;
<span class="kw">impl</span> <span class="ident">PartialEq</span> <span class="kw">for</span> <span class="ident">ProtoBufPayloadError</span> {
<span class="kw">fn</span> <span class="ident">eq</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">other</span>: <span class="kw-2">&amp;</span><span class="ident">ProtoBufPayloadError</span>) -&gt; <span class="ident">bool</span> {
<span class="kw">match</span> <span class="kw-2">*</span><span class="self">self</span> {
<span class="ident">ProtoBufPayloadError::Overflow</span> =&gt; {
<span class="macro">matches!</span>(<span class="kw-2">*</span><span class="ident">other</span>, <span class="ident">ProtoBufPayloadError::Overflow</span>)
<span class="kw">impl </span>PartialEq <span class="kw">for </span>ProtoBufPayloadError {
<span class="kw">fn </span>eq(<span class="kw-2">&amp;</span><span class="self">self</span>, other: <span class="kw-2">&amp;</span>ProtoBufPayloadError) -&gt; bool {
<span class="kw">match </span><span class="kw-2">*</span><span class="self">self </span>{
ProtoBufPayloadError::Overflow =&gt; {
<span class="macro">matches!</span>(<span class="kw-2">*</span>other, ProtoBufPayloadError::Overflow)
}
<span class="ident">ProtoBufPayloadError::ContentType</span> =&gt; {
<span class="macro">matches!</span>(<span class="kw-2">*</span><span class="ident">other</span>, <span class="ident">ProtoBufPayloadError::ContentType</span>)
ProtoBufPayloadError::ContentType =&gt; {
<span class="macro">matches!</span>(<span class="kw-2">*</span>other, ProtoBufPayloadError::ContentType)
}
<span class="kw">_</span> =&gt; <span class="bool-val">false</span>,
<span class="kw">_ </span>=&gt; <span class="bool-val">false</span>,
}
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">PartialEq</span>, <span class="ident">Eq</span>, <span class="ident">Message</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">MyObject</span> {
<span class="attribute">#[<span class="ident">prost</span>(<span class="ident">int32</span>, <span class="ident">tag</span> <span class="op">=</span> <span class="string">&quot;1&quot;</span>)]</span>
<span class="kw">pub</span> <span class="ident">number</span>: <span class="ident">i32</span>,
<span class="attribute">#[<span class="ident">prost</span>(<span class="ident">string</span>, <span class="ident">tag</span> <span class="op">=</span> <span class="string">&quot;2&quot;</span>)]</span>
<span class="kw">pub</span> <span class="ident">name</span>: <span class="ident">String</span>,
<span class="attribute">#[derive(Clone, PartialEq, Eq, Message)]
</span><span class="kw">pub struct </span>MyObject {
<span class="attribute">#[prost(int32, tag = <span class="string">&quot;1&quot;</span>)]
</span><span class="kw">pub </span>number: i32,
<span class="attribute">#[prost(string, tag = <span class="string">&quot;2&quot;</span>)]
</span><span class="kw">pub </span>name: String,
}
<span class="attribute">#[<span class="ident">actix_web::test</span>]</span>
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">test_protobuf</span>() {
<span class="kw">let</span> <span class="ident">protobuf</span> <span class="op">=</span> <span class="ident">ProtoBuf</span>(<span class="ident">MyObject</span> {
<span class="ident">number</span>: <span class="number">9</span>,
<span class="ident">name</span>: <span class="string">&quot;test&quot;</span>.<span class="ident">to_owned</span>(),
<span class="attribute">#[actix_web::test]
</span><span class="kw">async fn </span>test_protobuf() {
<span class="kw">let </span>protobuf = ProtoBuf(MyObject {
number: <span class="number">9</span>,
name: <span class="string">&quot;test&quot;</span>.to_owned(),
});
<span class="kw">let</span> <span class="ident">req</span> <span class="op">=</span> <span class="ident">TestRequest::default</span>().<span class="ident">to_http_request</span>();
<span class="kw">let</span> <span class="ident">resp</span> <span class="op">=</span> <span class="ident">protobuf</span>.<span class="ident">respond_to</span>(<span class="kw-2">&amp;</span><span class="ident">req</span>);
<span class="kw">let</span> <span class="ident">ct</span> <span class="op">=</span> <span class="ident">resp</span>.<span class="ident">headers</span>().<span class="ident">get</span>(<span class="ident">header::CONTENT_TYPE</span>).<span class="ident">unwrap</span>();
<span class="macro">assert_eq!</span>(<span class="ident">ct</span>, <span class="string">&quot;application/protobuf&quot;</span>);
<span class="kw">let </span>req = TestRequest::default().to_http_request();
<span class="kw">let </span>resp = protobuf.respond_to(<span class="kw-2">&amp;</span>req);
<span class="kw">let </span>ct = resp.headers().get(header::CONTENT_TYPE).unwrap();
<span class="macro">assert_eq!</span>(ct, <span class="string">&quot;application/protobuf&quot;</span>);
}
<span class="attribute">#[<span class="ident">actix_web::test</span>]</span>
<span class="kw">async</span> <span class="kw">fn</span> <span class="ident">test_protobuf_message</span>() {
<span class="kw">let</span> (<span class="ident">req</span>, <span class="kw-2">mut</span> <span class="ident">pl</span>) <span class="op">=</span> <span class="ident">TestRequest::default</span>().<span class="ident">to_http_parts</span>();
<span class="kw">let</span> <span class="ident">protobuf</span> <span class="op">=</span> <span class="ident">ProtoBufMessage</span>::<span class="op">&lt;</span><span class="ident">MyObject</span><span class="op">&gt;</span><span class="ident">::new</span>(<span class="kw-2">&amp;</span><span class="ident">req</span>, <span class="kw-2">&amp;mut</span> <span class="ident">pl</span>).<span class="kw">await</span>;
<span class="macro">assert_eq!</span>(<span class="ident">protobuf</span>.<span class="ident">err</span>().<span class="ident">unwrap</span>(), <span class="ident">ProtoBufPayloadError::ContentType</span>);
<span class="attribute">#[actix_web::test]
</span><span class="kw">async fn </span>test_protobuf_message() {
<span class="kw">let </span>(req, <span class="kw-2">mut </span>pl) = TestRequest::default().to_http_parts();
<span class="kw">let </span>protobuf = ProtoBufMessage::&lt;MyObject&gt;::new(<span class="kw-2">&amp;</span>req, <span class="kw-2">&amp;mut </span>pl).<span class="kw">await</span>;
<span class="macro">assert_eq!</span>(protobuf.err().unwrap(), ProtoBufPayloadError::ContentType);
<span class="kw">let</span> (<span class="ident">req</span>, <span class="kw-2">mut</span> <span class="ident">pl</span>) <span class="op">=</span> <span class="ident">TestRequest::get</span>()
.<span class="ident">insert_header</span>((<span class="ident">header::CONTENT_TYPE</span>, <span class="string">&quot;application/text&quot;</span>))
.<span class="ident">to_http_parts</span>();
<span class="kw">let</span> <span class="ident">protobuf</span> <span class="op">=</span> <span class="ident">ProtoBufMessage</span>::<span class="op">&lt;</span><span class="ident">MyObject</span><span class="op">&gt;</span><span class="ident">::new</span>(<span class="kw-2">&amp;</span><span class="ident">req</span>, <span class="kw-2">&amp;mut</span> <span class="ident">pl</span>).<span class="kw">await</span>;
<span class="macro">assert_eq!</span>(<span class="ident">protobuf</span>.<span class="ident">err</span>().<span class="ident">unwrap</span>(), <span class="ident">ProtoBufPayloadError::ContentType</span>);
<span class="kw">let </span>(req, <span class="kw-2">mut </span>pl) = TestRequest::get()
.insert_header((header::CONTENT_TYPE, <span class="string">&quot;application/text&quot;</span>))
.to_http_parts();
<span class="kw">let </span>protobuf = ProtoBufMessage::&lt;MyObject&gt;::new(<span class="kw-2">&amp;</span>req, <span class="kw-2">&amp;mut </span>pl).<span class="kw">await</span>;
<span class="macro">assert_eq!</span>(protobuf.err().unwrap(), ProtoBufPayloadError::ContentType);
<span class="kw">let</span> (<span class="ident">req</span>, <span class="kw-2">mut</span> <span class="ident">pl</span>) <span class="op">=</span> <span class="ident">TestRequest::get</span>()
.<span class="ident">insert_header</span>((<span class="ident">header::CONTENT_TYPE</span>, <span class="string">&quot;application/protobuf&quot;</span>))
.<span class="ident">insert_header</span>((<span class="ident">header::CONTENT_LENGTH</span>, <span class="string">&quot;10000&quot;</span>))
.<span class="ident">to_http_parts</span>();
<span class="kw">let</span> <span class="ident">protobuf</span> <span class="op">=</span> <span class="ident">ProtoBufMessage</span>::<span class="op">&lt;</span><span class="ident">MyObject</span><span class="op">&gt;</span><span class="ident">::new</span>(<span class="kw-2">&amp;</span><span class="ident">req</span>, <span class="kw-2">&amp;mut</span> <span class="ident">pl</span>)
.<span class="ident">limit</span>(<span class="number">100</span>)
<span class="kw">let </span>(req, <span class="kw-2">mut </span>pl) = TestRequest::get()
.insert_header((header::CONTENT_TYPE, <span class="string">&quot;application/protobuf&quot;</span>))
.insert_header((header::CONTENT_LENGTH, <span class="string">&quot;10000&quot;</span>))
.to_http_parts();
<span class="kw">let </span>protobuf = ProtoBufMessage::&lt;MyObject&gt;::new(<span class="kw-2">&amp;</span>req, <span class="kw-2">&amp;mut </span>pl)
.limit(<span class="number">100</span>)
.<span class="kw">await</span>;
<span class="macro">assert_eq!</span>(<span class="ident">protobuf</span>.<span class="ident">err</span>().<span class="ident">unwrap</span>(), <span class="ident">ProtoBufPayloadError::Overflow</span>);
<span class="macro">assert_eq!</span>(protobuf.err().unwrap(), ProtoBufPayloadError::Overflow);
}
}
</code></pre></div>
</section></div></main><div id="rustdoc-vars" data-root-path="../../" data-current-crate="actix_protobuf" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.65.0-nightly (34a6cae28 2022-08-09)" ></div></body></html>
</section></div></main><div id="rustdoc-vars" data-root-path="../../" data-current-crate="actix_protobuf" data-themes="ayu,dark,light" data-resource-suffix="" data-rustdoc-version="1.65.0-nightly (060e47f74 2022-08-23)" ></div></body></html>