Skip to main content

async_zip/date/
builder.rs

1// Copyright (c) 2024 Harry [Majored] [hello@majored.pw]
2// MIT License (https://github.com/Majored/rs-async-zip/blob/main/LICENSE)
3
4use crate::ZipDateTime;
5
6/// A builder for [`ZipDateTime`].
7pub struct ZipDateTimeBuilder(pub(crate) ZipDateTime);
8
9impl From<ZipDateTime> for ZipDateTimeBuilder {
10    fn from(date: ZipDateTime) -> Self {
11        Self(date)
12    }
13}
14
15impl Default for ZipDateTimeBuilder {
16    fn default() -> Self {
17        Self::new()
18    }
19}
20
21impl ZipDateTimeBuilder {
22    /// Constructs a new builder which defines the raw underlying data of a ZIP entry.
23    pub fn new() -> Self {
24        Self(ZipDateTime { date: 0, time: 0 })
25    }
26
27    /// Sets the date and time's year.
28    pub fn year(mut self, year: i32) -> Self {
29        let year: u16 = (((year - 1980) << 9) & 0xFE00).try_into().unwrap();
30        self.0.date |= year;
31        self
32    }
33
34    /// Sets the date and time's month.
35    pub fn month(mut self, month: u32) -> Self {
36        let month: u16 = ((month << 5) & 0x1E0).try_into().unwrap();
37        self.0.date |= month;
38        self
39    }
40
41    /// Sets the date and time's day.
42    pub fn day(mut self, day: u32) -> Self {
43        let day: u16 = (day & 0x1F).try_into().unwrap();
44        self.0.date |= day;
45        self
46    }
47
48    /// Sets the date and time's hour.
49    pub fn hour(mut self, hour: u32) -> Self {
50        let hour: u16 = ((hour << 11) & 0xF800).try_into().unwrap();
51        self.0.time |= hour;
52        self
53    }
54
55    /// Sets the date and time's minute.
56    pub fn minute(mut self, minute: u32) -> Self {
57        let minute: u16 = ((minute << 5) & 0x7E0).try_into().unwrap();
58        self.0.time |= minute;
59        self
60    }
61
62    /// Sets the date and time's second.
63    ///
64    /// Note that MS-DOS has a maximum granularity of two seconds.
65    pub fn second(mut self, second: u32) -> Self {
66        let second: u16 = ((second >> 1) & 0x1F).try_into().unwrap();
67        self.0.time |= second;
68        self
69    }
70
71    /// Consumes this builder and returns a final [`ZipDateTime`].
72    ///
73    /// This is equivalent to:
74    /// ```
75    /// # use async_zip::{ZipDateTime, ZipDateTimeBuilder, Compression};
76    /// #
77    /// # let builder = ZipDateTimeBuilder::new().year(2024).month(3).day(2);
78    /// let date: ZipDateTime = builder.into();
79    /// ```
80    pub fn build(self) -> ZipDateTime {
81        self.into()
82    }
83}