summaryrefslogtreecommitdiffstats
path: root/openpgp/src/literal.rs
blob: 3b66d0c1a267287f7cbbeb613a56261a8f7629c9 (plain)
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
use std::fmt;
use std::cmp;
use time;

use conversions::Time;
use Literal;
use Packet;

impl fmt::Debug for Literal {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let filename = if let Some(ref filename) = self.filename {
            Some(String::from_utf8_lossy(filename))
        } else {
            None
        };

        let body = if let Some(ref body) = self.common.body {
            &body[..]
        } else {
            &b""[..]
        };

        let threshold = 36;
        let prefix = &body[..cmp::min(threshold, body.len())];
        let mut prefix_fmt = String::from_utf8_lossy(prefix).into_owned();
        if body.len() > threshold {
            prefix_fmt.push_str("...");
        }
        prefix_fmt.push_str(&format!(" ({} bytes)", body.len())[..]);

        f.debug_struct("Literal")
            .field("format", &(self.format as char))
            .field("filename", &filename)
            .field("date", &self.date)
            .field("body", &prefix_fmt)
            .finish()
    }
}

impl Literal {
    /// Returns a new `Literal` packet.
    pub fn new(format: char) -> Literal {
        Literal {
            common: Default::default(),
            format: format as u8,
            filename: None,
            date: time::Tm::from_pgp(0),
        }
    }

    /// Sets the Literal packet's body to the provided byte string.
    pub fn body(mut self, data: Vec<u8>) -> Literal {
        self.common.body = Some(data);
        self
    }

    /// Sets the Literal packet's content disposition to text.
    ///
    /// This is a hint that the content is probably text; the encoding
    /// is not specified.
    pub fn text(mut self) -> Literal {
        self.format = 't' as u8;
        self
    }

    /// Sets the Literal packet's content disposition to UTF-8.
    ///
    /// This is a hint that the content is probably UTF-8 encoded.
    pub fn utf8(mut self) -> Literal {
        self.format = 'u' as u8;
        self
    }

    /// Sets the Literal packet's content disposition to binary.
    ///
    /// This is a hint that the content is probably binary data.
    pub fn binary(mut self) -> Literal {
        self.format = 'b' as u8;
        self
    }

    /// Sets the Literal packet's content disposition to MIME.
    ///
    /// This is specified in RFC 4880bis, which has not yet been
    /// standardized.
    pub fn mime(mut self) -> Literal {
        self.format = 'm' as u8;
        self
    }

    /// Sets the literal packet's filename field from a byte sequence.
    ///
    /// The standard does not specify the encoding.
    ///
    /// This function panics, if the filename is longer than 255
    /// bytes, which is the limit imposed by RFC 4880.
    pub fn filename_from_bytes(mut self, filename: &[u8]) -> Literal {
        if filename.len() > 255 {
            panic!("Filename too long.");
        }
        self.filename = Some(filename.to_vec());
        self
    }

    /// Sets the literal packet's filename field from a UTF-8 encoded
    /// string.
    ///
    /// This is a convenience function, since the field is actually a
    /// raw byte string.
    ///
    /// This function panics, if the filename is longer than 255
    /// bytes, which is the limit imposed by RFC 4880.
    pub fn filename(mut self, filename: &str) -> Literal {
        if filename.len() > 255 {
            panic!("Filename too long.");
        }
        self.filename = Some(filename.as_bytes().to_vec());
        self
    }

    /// Sets the literal packet's date field using a Unix timestamp.
    ///
    /// A Unix timestamp is the number of seconds since the Unix
    /// epoch.
    pub fn date(mut self, timestamp: time::Tm) -> Literal {
        self.date = timestamp;
        self
    }

    /// Convert the `Literal` struct to a `Packet`.
    pub fn to_packet(self) -> Packet {
        Packet::Literal(self)
    }
}