# if_range.rs.html -- source
Source to the Rust file `src/header/common/if_range.rs`.
Keywords: rust, rustlang, rust-lang

      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

    use error::ParseError;
    use header::from_one_raw_str;
    use header::{EntityTag, Header, HeaderName, HeaderValue, HttpDate, IntoHeaderValue,
                 InvalidHeaderValueBytes, Writer};
    use http::header;
    use httpmessage::HttpMessage;
    use std::fmt::{self, Display, Write};

    /// `If-Range` header, defined in [RFC7233](http://tools.ietf.org/html/rfc7233#section-3.2)
    ///
    /// If a client has a partial copy of a representation and wishes to have
    /// an up-to-date copy of the entire representation, it could use the
    /// Range header field with a conditional GET (using either or both of
    /// If-Unmodified-Since and If-Match.)  However, if the precondition
    /// fails because the representation has been modified, the client would
    /// then have to make a second request to obtain the entire current
    /// representation.
    ///
    /// The `If-Range` header field allows a client to \"short-circuit\" the
    /// second request.  Informally, its meaning is as follows: if the
    /// representation is unchanged, send me the part(s) that I am requesting
    /// in Range; otherwise, send me the entire representation.
    ///
    /// # ABNF
    ///
    /// ```text
    /// If-Range = entity-tag / HTTP-date
    /// ```
    ///
    /// # Example values
    ///
    /// * `Sat, 29 Oct 1994 19:43:31 GMT`
    /// * `\"xyzzy\"`
    ///
    /// # Examples
    ///
    /// ```rust
    /// use actix_web::HttpResponse;
    /// use actix_web::http::header::{EntityTag, IfRange};
    ///
    /// let mut builder = HttpResponse::Ok();
    /// builder.set(IfRange::EntityTag(EntityTag::new(
    ///     false,
    ///     "xyzzy".to_owned(),
    /// )));
    /// ```
    ///
    /// ```rust
    /// use actix_web::HttpResponse;
    /// use actix_web::http::header::IfRange;
    /// use std::time::{Duration, SystemTime};
    ///
    /// let mut builder = HttpResponse::Ok();
    /// let fetched = SystemTime::now() - Duration::from_secs(60 * 60 * 24);
    /// builder.set(IfRange::Date(fetched.into()));
    /// ```
    #[derive(Clone, Debug, PartialEq)]
    pub enum IfRange {
        /// The entity-tag the client has of the resource
        EntityTag(EntityTag),
        /// The date when the client retrieved the resource
        Date(HttpDate),
    }

    impl Header for IfRange {
        fn name() -> HeaderName {
            header::IF_RANGE
        }
        #[inline]
        fn parse<T>(msg: &T) -> Result<Self, ParseError>
        where
            T: HttpMessage,
        {
            let etag: Result<EntityTag, _> =
                from_one_raw_str(msg.headers().get(header::IF_RANGE));
            if let Ok(etag) = etag {
                return Ok(IfRange::EntityTag(etag));
            }
            let date: Result<HttpDate, _> =
                from_one_raw_str(msg.headers().get(header::IF_RANGE));
            if let Ok(date) = date {
                return Ok(IfRange::Date(date));
            }
            Err(ParseError::Header)
        }
    }

    impl Display for IfRange {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            match *self {
                IfRange::EntityTag(ref x) => Display::fmt(x, f),
                IfRange::Date(ref x) => Display::fmt(x, f),
            }
        }
    }

    impl IntoHeaderValue for IfRange {
        type Error = InvalidHeaderValueBytes;

        fn try_into(self) -> Result<HeaderValue, Self::Error> {
            let mut writer = Writer::new();
            let _ = write!(&mut writer, "{}", self);
            HeaderValue::from_shared(writer.take())
        }
    }

    #[cfg(test)]
    mod test_if_range {
        use super::IfRange as HeaderField;
        use header::*;
        use std::str;
        test_header!(test1, vec![b"Sat, 29 Oct 1994 19:43:31 GMT"]);
        test_header!(test2, vec![b"\"xyzzy\""]);
        test_header!(test3, vec![b"this-is-invalid"], None::<IfRange>);
    }

# Help

## Keyboard Shortcuts

`?`
  Show this help dialog
`S`
  Focus the search field
`↑`
  Move up in search results
`↓`
  Move down in search results
`↹`
  Switch tab
`⏎`
  Go to active search result
`+`
  Expand all sections
`-`
  Collapse all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g. `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g. `vec -> usize` or `* -> vec`)

Search multiple things at once by splitting your query with comma (e.g. `str,u8` or `String,struct:Vec,test`)