Skip to content

Commit 3b7b3f9

Browse files
committed
Add optional defmt support
1 parent 4c42ee5 commit 3b7b3f9

File tree

14 files changed

+115
-0
lines changed

14 files changed

+115
-0
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ name = "chrono"
2020
# Don't forget to adjust `ALL_NON_EXCLUSIVE_FEATURES` in CI scripts when adding a feature or an optional dependency.
2121
default = ["clock", "std", "oldtime", "wasmbind"]
2222
alloc = []
23+
defmt = ["dep:defmt"]
2324
libc = []
2425
winapi = ["windows-targets"]
2526
std = ["alloc"]
@@ -43,6 +44,7 @@ serde = { version = "1.0.99", default-features = false, optional = true }
4344
pure-rust-locales = { version = "0.8", optional = true }
4445
rkyv = { version = "0.7.43", optional = true, default-features = false }
4546
arbitrary = { version = "1.0.0", features = ["derive"], optional = true }
47+
defmt = { version = "0.3", optional = true }
4648

4749
[target.'cfg(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))'.dependencies]
4850
wasm-bindgen = { version = "0.2", optional = true }

src/date.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,16 @@ where
551551
}
552552
}
553553

554+
#[cfg(feature = "defmt")]
555+
impl<Tz: TimeZone> defmt::Format for Date<Tz>
556+
where
557+
Tz::Offset: defmt::Format,
558+
{
559+
fn format(&self, fmt: defmt::Formatter) {
560+
defmt::write!(fmt, "{}{}", self.naive_local(), self.offset);
561+
}
562+
}
563+
554564
// Note that implementation of Arbitrary cannot be automatically derived for Date<Tz>, due to
555565
// the nontrivial bound <Tz as TimeZone>::Offset: Arbitrary.
556566
#[cfg(all(feature = "arbitrary", feature = "std"))]

src/datetime/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1761,6 +1761,16 @@ impl<Tz: TimeZone> fmt::Debug for DateTime<Tz> {
17611761
}
17621762
}
17631763

1764+
#[cfg(feature = "defmt")]
1765+
impl<Tz: TimeZone> defmt::Format for DateTime<Tz>
1766+
where
1767+
Tz::Offset: defmt::Format,
1768+
{
1769+
fn format(&self, fmt: defmt::Formatter) {
1770+
defmt::write!(fmt, "{}{}", self.overflowing_naive_local(), self.offset);
1771+
}
1772+
}
1773+
17641774
// `fmt::Debug` is hand implemented for the `rkyv::Archive` variant of `DateTime` because
17651775
// deriving a trait recursively does not propagate trait defined associated types with their own
17661776
// constraints:

src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,13 @@ impl fmt::Debug for OutOfRange {
684684
}
685685
}
686686

687+
#[cfg(feature = "defmt")]
688+
impl defmt::Format for OutOfRange {
689+
fn format(&self, fmt: defmt::Formatter) {
690+
defmt::write!(fmt, "out of range");
691+
}
692+
}
693+
687694
#[cfg(feature = "std")]
688695
impl std::error::Error for OutOfRange {}
689696

src/month.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,13 @@ impl fmt::Debug for ParseMonthError {
284284
}
285285
}
286286

287+
#[cfg(feature = "defmt")]
288+
impl defmt::Format for ParseMonthError {
289+
fn format(&self, fmt: defmt::Formatter) {
290+
defmt::write!(fmt, "ParseMonthError {{ .. }}")
291+
}
292+
}
293+
287294
#[cfg(feature = "serde")]
288295
mod month_serde {
289296
use super::Month;

src/naive/date/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2128,6 +2128,7 @@ impl From<NaiveDateTime> for NaiveDate {
21282128

21292129
/// Iterator over `NaiveDate` with a step size of one day.
21302130
#[derive(Debug, Copy, Clone, Hash, PartialEq, PartialOrd, Eq, Ord)]
2131+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
21312132
pub struct NaiveDateDaysIterator {
21322133
value: NaiveDate,
21332134
}
@@ -2164,6 +2165,7 @@ impl FusedIterator for NaiveDateDaysIterator {}
21642165

21652166
/// Iterator over `NaiveDate` with a step size of one week.
21662167
#[derive(Debug, Copy, Clone, Hash, PartialEq, PartialOrd, Eq, Ord)]
2168+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
21672169
pub struct NaiveDateWeeksIterator {
21682170
value: NaiveDate,
21692171
}
@@ -2238,6 +2240,23 @@ impl fmt::Debug for NaiveDate {
22382240
}
22392241
}
22402242

2243+
#[cfg(feature = "defmt")]
2244+
impl defmt::Format for NaiveDate {
2245+
fn format(&self, fmt: defmt::Formatter) {
2246+
let year = self.year();
2247+
let mdf = self.mdf();
2248+
if (0..=9999).contains(&year) {
2249+
defmt::write!(fmt, "{:02}{:02}", year / 100, year % 100);
2250+
} else {
2251+
// ISO 8601 requires the explicit sign for out-of-range years
2252+
let sign = ['+', '-'][(year < 0) as usize];
2253+
defmt::write!(fmt, "{}{:05}", sign, year.abs());
2254+
}
2255+
2256+
defmt::write!(fmt, "-{:02}-{:02}", mdf.month(), mdf.day());
2257+
}
2258+
}
2259+
22412260
/// The `Display` output of the naive date `d` is the same as
22422261
/// [`d.format("%Y-%m-%d")`](crate::format::strftime).
22432262
///

src/naive/datetime/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,6 +2053,13 @@ impl fmt::Debug for NaiveDateTime {
20532053
}
20542054
}
20552055

2056+
#[cfg(feature = "defmt")]
2057+
impl defmt::Format for NaiveDateTime {
2058+
fn format(&self, fmt: defmt::Formatter) {
2059+
defmt::write!(fmt, "{}T{}", self.date, self.time);
2060+
}
2061+
}
2062+
20562063
/// The `Display` output of the naive date and time `dt` is the same as
20572064
/// [`dt.format("%Y-%m-%d %H:%M:%S%.f")`](crate::format::strftime).
20582065
///

src/naive/isoweek.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,21 @@ impl fmt::Debug for IsoWeek {
160160
}
161161
}
162162

163+
#[cfg(feature = "defmt")]
164+
impl defmt::Format for IsoWeek {
165+
fn format(&self, fmt: defmt::Formatter) {
166+
let year = self.year();
167+
let week = self.week();
168+
if (0..=9999).contains(&year) {
169+
defmt::write!(fmt, "{:04}-W{:02}", year, week)
170+
} else {
171+
// ISO 8601 requires the explicit sign for out-of-range years
172+
let sign = ['+', '-'][(year < 0) as usize];
173+
defmt::write!(fmt, "{}{:05}-W{:02}", sign, year.abs(), week)
174+
}
175+
}
176+
}
177+
163178
#[cfg(test)]
164179
mod tests {
165180
#[cfg(feature = "rkyv-validation")]

src/naive/time/mod.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,6 +1529,31 @@ impl fmt::Debug for NaiveTime {
15291529
}
15301530
}
15311531

1532+
#[cfg(feature = "defmt")]
1533+
impl defmt::Format for NaiveTime {
1534+
fn format(&self, fmt: defmt::Formatter) {
1535+
let (hour, min, sec) = self.hms();
1536+
let (sec, nano) = if self.frac >= 1_000_000_000 {
1537+
(sec + 1, self.frac - 1_000_000_000)
1538+
} else {
1539+
(sec, self.frac)
1540+
};
1541+
1542+
let (hour, min, sec) = (hour as u8, min as u8, sec as u8);
1543+
defmt::write!(fmt, "{:02}:{:02}:{:02}", hour, min, sec);
1544+
1545+
if nano == 0 {
1546+
return;
1547+
} else if nano % 1_000_000 == 0 {
1548+
defmt::write!(fmt, ".{:03}", nano / 1_000_000);
1549+
} else if nano % 1_000 == 0 {
1550+
defmt::write!(fmt, ".{:06}", nano / 1_000);
1551+
} else {
1552+
defmt::write!(fmt, ".{:09}", nano);
1553+
}
1554+
}
1555+
}
1556+
15321557
/// The `Display` output of the naive time `t` is the same as
15331558
/// [`t.format("%H:%M:%S%.f")`](crate::format::strftime).
15341559
///

src/offset/fixed.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use crate::naive::{NaiveDate, NaiveDateTime};
2727
archive_attr(derive(Clone, Copy, PartialEq, Eq, Hash, Debug))
2828
)]
2929
#[cfg_attr(feature = "rkyv-validation", archive(check_bytes))]
30+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
3031
pub struct FixedOffset {
3132
local_minus_utc: i32,
3233
}

0 commit comments

Comments
 (0)