Skip to main content

FromForm

Trait FromForm 

Source
pub trait FromForm: Sized {
    type Builder: FormBuilder<Output = Self> + Default;

    // Provided methods
    fn from_urlencoded(input: &[u8]) -> Result<Self, FormError> { ... }
    fn from_query(query: &[u8]) -> Result<Self, FormError> { ... }
    fn from_multipart(
        content_type: &[u8],
        body: &[u8],
    ) -> Result<Self, FormError> { ... }
    fn from_body(content_type: &[u8], body: &[u8]) -> Result<Self, FormError> { ... }
    fn from_urlencoded_with(
        input: &[u8],
        limits: &Limits,
        policy: &Policy,
    ) -> Result<Self, FormError> { ... }
    fn from_body_with(
        content_type: &[u8],
        body: &[u8],
        limits: &Limits,
        policy: &Policy,
    ) -> Result<Self, FormError> { ... }
    fn from_body_inspected<I: Inspector>(
        content_type: &[u8],
        body: &[u8],
        limits: &Limits,
        policy: &Policy,
        inspector: &mut I,
    ) -> Result<Self, FormError> { ... }
    fn from_body_all(
        content_type: &[u8],
        body: &[u8],
    ) -> Result<Self, FormErrors> { ... }
    fn from_body_all_with(
        content_type: &[u8],
        body: &[u8],
        limits: &Limits,
        policy: &Policy,
    ) -> Result<Self, FormErrors> { ... }
    fn from_upload_mut(upload: &mut Upload) -> Result<Self, FormError> { ... }
    fn from_upload(upload: Upload) -> Result<Self, FormError> { ... }
}
Available on crate feature alloc only.
Expand description

A struct that can be read from a form. Implemented by form!; every method is provided.

§Examples

use form_net::FromForm;

form_net::form! {
    pub struct Login {
        pub email: String,
        pub password: form_net::Secret,
        pub remember: bool,
    }
    ignore = ["csrf_token"];
}

let login = Login::from_body(b"application/x-www-form-urlencoded", b"email=a%40b.example&password=x&csrf_token=t")?;
assert_eq!((login.email.as_str(), login.remember), ("a@b.example", false));

Required Associated Types§

Source

type Builder: FormBuilder<Output = Self> + Default

The builder that collects the fields.

Provided Methods§

Source

fn from_urlencoded(input: &[u8]) -> Result<Self, FormError>

From a urlencoded body, with the default limits and policy.

§Errors

The parser’s errors; Extract { .. }.

§Examples
use form_net::FromForm;

let s = Search::from_urlencoded(b"q=rust+forms&page=2")?;
assert_eq!((s.q.as_str(), s.page), ("rust forms", 2));
Source

fn from_query(query: &[u8]) -> Result<Self, FormError>

From a query string; one leading ? is stripped.

§Errors

As from_urlencoded.

§Examples
use form_net::FromForm;

let s = Search::from_query(b"?q=rust&page=1")?;
assert_eq!((s.q.as_str(), s.page), ("rust", 1));
Source

fn from_multipart(content_type: &[u8], body: &[u8]) -> Result<Self, FormError>

From a buffered multipart/form-data body.

§Errors

The parser’s errors; Extract { .. }.

§Examples
use form_net::FromForm;

let body = b"--X\r\nContent-Disposition: form-data; name=title\r\n\r\nHi\r\n--X--";
let note = Note::from_multipart(b"multipart/form-data; boundary=X", body)?;
assert_eq!(note.title, "Hi");
Source

fn from_body(content_type: &[u8], body: &[u8]) -> Result<Self, FormError>

From either encoding, by the Content-Type.

§Errors

UnsupportedMediaType; the parsers’ errors; Extract { .. }.

§Examples
use form_net::FromForm;

let s = Search::from_body(b"application/x-www-form-urlencoded", b"q=a&page=3")?;
assert_eq!(s.page, 3);
let err = Search::from_body(b"application/json", b"{}").unwrap_err();
assert_eq!(err.code(), "unsupported_media_type");
Source

fn from_urlencoded_with( input: &[u8], limits: &Limits, policy: &Policy, ) -> Result<Self, FormError>

From a urlencoded body with explicit limits and policy.

§Errors

As from_urlencoded; InvalidLimits.

§Examples
use form_net::{FromForm, Limits, Policy};

let limits = Limits::DEFAULT.with_max_body_bytes(16);
let r = Search::from_urlencoded_with(b"q=a-long-search-term&page=1", &limits, &Policy::DEFAULT);
assert_eq!(r.unwrap_err().code(), "limit.body");
Source

fn from_body_with( content_type: &[u8], body: &[u8], limits: &Limits, policy: &Policy, ) -> Result<Self, FormError>

From either encoding with explicit limits and policy.

§Errors

As from_body; InvalidLimits.

§Examples
use form_net::{FromForm, Limits, Policy};

let limits = Limits::DEFAULT.with_max_fields(1);
let ct = b"application/x-www-form-urlencoded";
let err = Search::from_body_with(ct, b"q=a&page=1", &limits, &Policy::DEFAULT).unwrap_err();
assert_eq!(err.code(), "limit.fields");
Source

fn from_body_inspected<I: Inspector>( content_type: &[u8], body: &[u8], limits: &Limits, policy: &Policy, inspector: &mut I, ) -> Result<Self, FormError>

From either encoding, with an inspector in the same pass: the inspector and the struct see the same bytes.

§Errors

As from_body_with; Refused.

§Examples
use form_net::{FromForm, Inspector, Limits, Policy, Refusal, Verdict};

struct NoAdmin;
impl Inspector for NoAdmin {
    fn field(&mut self, name: &str, _value: &[u8]) -> Verdict {
        if name == "admin" { Verdict::Refuse(Refusal::new(403, "app.admin")) } else { Verdict::Continue }
    }
}

let ct = b"application/x-www-form-urlencoded";
let r = Search::from_body_inspected(ct, b"admin=1&q=a", &Limits::DEFAULT, &Policy::DEFAULT, &mut NoAdmin);
assert_eq!(r.unwrap_err().code(), "app.admin");
Source

fn from_body_all(content_type: &[u8], body: &[u8]) -> Result<Self, FormErrors>

From either encoding, collecting every field’s error instead of stopping at the first (D-090), so a form can be shown again with a message beside each field.

§Errors

FormErrors: the parse error alone, or every extraction error.

§Examples
use form_net::{ExtractError, FromForm};

let errors = Search::from_body_all(b"application/x-www-form-urlencoded", b"page=x").unwrap_err();
assert_eq!(errors.field("page"), Some(ExtractError::Invalid("not a whole number")));
assert_eq!(errors.field("q"), Some(ExtractError::Missing));
Source

fn from_body_all_with( content_type: &[u8], body: &[u8], limits: &Limits, policy: &Policy, ) -> Result<Self, FormErrors>

As from_body_all, with explicit limits and policy.

§Errors

As from_body_all; InvalidLimits.

§Examples
use form_net::{FromForm, Limits, Policy};

let limits = Limits::DEFAULT.with_max_body_bytes(8);
let ct = b"application/x-www-form-urlencoded";
let errors = Search::from_body_all_with(ct, b"q=a&page=10", &limits, &Policy::DEFAULT).unwrap_err();
// A parse error stops the parse and is the only error.
assert_eq!((errors.len(), errors.status_hint()), (1, 413));
Source

fn from_upload_mut(upload: &mut Upload) -> Result<Self, FormError>

Available on crate feature fs only.

From an upload that stays usable (D-090): text fields are read by reference, and only the files the struct declares are moved out of it; files under ignore = [..] names stay in the upload for the caller. Unknown names are refused as in from_upload. On error, files already moved into the builder are dropped (deleted).

§Errors

Extract { .. }.

§Examples
use form_net::FromForm;

form_net::form! {
    pub struct Post { pub title: String, pub cover: form_net::StoredFile }
    ignore = ["attachment"];
}

let body = b"--X\r\nContent-Disposition: form-data; name=title\r\n\r\nHi\r\n--X\r\nContent-Disposition: form-data; name=cover; filename=c.png\r\n\r\nC\r\n--X\r\nContent-Disposition: form-data; name=attachment; filename=a.pdf\r\n\r\nA\r\n--X--";
let mut upload = form_net::read_multipart(b"multipart/form-data; boundary=X", &body[..])?;
let post = Post::from_upload_mut(&mut upload)?;
assert_eq!((post.title.as_str(), post.cover.len()), ("Hi", 1));
assert_eq!(upload.field("title"), Some("Hi"));
assert!(upload.file("cover").is_none() && upload.file("attachment").is_some());
Source

fn from_upload(upload: Upload) -> Result<Self, FormError>

Available on crate feature fs only.

From a finished upload: text fields as text, files moved into the struct as StoredFiles.

§Errors

Extract { .. }.

§Examples
use form_net::FromForm;

form_net::form! { pub struct Post { pub title: String, pub cover: form_net::StoredFile } }

let body = b"--X\r\nContent-Disposition: form-data; name=title\r\n\r\nHi\r\n--X\r\nContent-Disposition: form-data; name=cover; filename=c.png\r\n\r\nC\r\n--X--";
let upload = form_net::read_multipart(b"multipart/form-data; boundary=X", &body[..])?;
let post = Post::from_upload(upload)?;
assert_eq!((post.title.as_str(), post.cover.len()), ("Hi", 1));

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§