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
use crate::*;

use std::io::{
    Error as IoError,
    ErrorKind as IoErrorKind,
    Result as IoResult
};

/// Sip Request Generator. When build is called the struct
/// is consumed and produces a SipMessage::Request variant.
/// Calling the `method` & `uri` methods before the `build`
/// method is required.
#[derive(Default)]
pub struct RequestGenerator {
    method: Option<Method>,
    uri: Option<Uri>,
    version: Version,
    headers: Headers,
    body: Vec<u8>,
}

impl RequestGenerator {
    /// Create a new instance.
    pub fn new() -> RequestGenerator {
        RequestGenerator {
            method: None,
            uri: None,
            version: Version::default(),
            headers: Headers::new(),
            body: vec![],
        }
    }

    /// Set the sip request method.
    pub fn method(mut self, method: Method) -> RequestGenerator {
        self.method = Some(method);
        self
    }

    /// Set the sip request uri.
    pub fn uri(mut self, uri: Uri) -> RequestGenerator {
        self.uri = Some(uri);
        self
    }

    /// Add multiple headers to the request header list.
    /// This use's Vec::extend so that the current items
    /// in the header list are kept.
    pub fn headers(mut self, headers: Vec<Header>) -> RequestGenerator {
        self.headers.extend(headers);
        self
    }

    /// Add a single header to the request header list.
    pub fn header(mut self, header: Header) -> RequestGenerator {
        self.headers.push(header);
        self
    }

    /// Get a reference to the header list.
    pub fn header_ref(&self) -> &Headers {
        &self.headers
    }

    /// Get a mutable reference to the header list.
    pub fn headers_ref_mut(&mut self) -> &mut Headers {
        &mut self.headers
    }

    /// Set the sip request body. This completely replaces
    /// the current request body.
    pub fn body(mut self, body: Vec<u8>) -> RequestGenerator {
        self.body = body;
        self
    }

    /// Build the sip request.
    pub fn build(self) -> IoResult<SipMessage> {
        if let Some(method) = self.method {
            if let Some(uri) = self.uri {
                Ok(SipMessage::Request {
                    method,
                    uri,
                    version: self.version,
                    headers: self.headers,
                    body: self.body,
                })
            } else {
                Err(IoError::new(
                    IoErrorKind::InvalidInput,
                    "`uri` method call required",
                ))
            }
        } else {
            Err(IoError::new(
                IoErrorKind::InvalidInput,
                "`method` method call required",
            ))
        }
    }
}