|
1 | 1 | use core::fmt; |
2 | 2 | use core::num::NonZeroU32; |
| 3 | +use core::time::Duration; |
3 | 4 |
|
4 | 5 | use crate::{expect, try_opt}; |
| 6 | +use crate::{Days, Months}; |
5 | 7 |
|
6 | 8 | /// ISO 8601 duration type. |
7 | 9 | /// |
@@ -268,9 +270,31 @@ impl CalendarDuration { |
268 | 270 | } |
269 | 271 | } |
270 | 272 |
|
| 273 | +impl From<Days> for CalendarDuration { |
| 274 | + fn from(value: Days) -> Self { |
| 275 | + let days = u32::try_from(value.0).expect("value of `Days` out of range"); |
| 276 | + Self::new().days(days) |
| 277 | + } |
| 278 | +} |
| 279 | + |
| 280 | +impl From<Months> for CalendarDuration { |
| 281 | + fn from(value: Months) -> Self { |
| 282 | + Self::new().months(value.0) |
| 283 | + } |
| 284 | +} |
| 285 | + |
| 286 | +impl From<Duration> for CalendarDuration { |
| 287 | + fn from(value: Duration) -> Self { |
| 288 | + let seconds = u32::try_from(value.as_secs()).expect("value of `Duration` out of range"); |
| 289 | + Self::new().seconds(seconds).nanos(value.subsec_nanos()).unwrap() |
| 290 | + } |
| 291 | +} |
| 292 | + |
271 | 293 | #[cfg(test)] |
272 | 294 | mod tests { |
273 | 295 | use super::CalendarDuration; |
| 296 | + use crate::{Days, Months}; |
| 297 | + use std::time::Duration; |
274 | 298 |
|
275 | 299 | #[test] |
276 | 300 | fn test_basic_functionality() { |
@@ -301,6 +325,28 @@ mod tests { |
301 | 325 | assert!(CalendarDuration::new().is_zero()); |
302 | 326 | } |
303 | 327 |
|
| 328 | + #[test] |
| 329 | + fn test_from_impls() { |
| 330 | + assert_eq!(CalendarDuration::new().days(5), Days::new(5).into()); |
| 331 | + assert_eq!(CalendarDuration::new().months(5), Months::new(5).into()); |
| 332 | + assert_eq!( |
| 333 | + CalendarDuration::new().seconds(7).nanos(8).unwrap(), |
| 334 | + Duration::new(7, 8).into() |
| 335 | + ); |
| 336 | + } |
| 337 | + |
| 338 | + #[test] |
| 339 | + #[should_panic] |
| 340 | + fn test_from_extreme_days_panics() { |
| 341 | + let _ = CalendarDuration::from(Days::new(1 << 32)); |
| 342 | + } |
| 343 | + |
| 344 | + #[test] |
| 345 | + #[should_panic] |
| 346 | + fn test_from_extreme_duration_panics() { |
| 347 | + let _ = CalendarDuration::from(Duration::new(1 << 32, 0)); |
| 348 | + } |
| 349 | + |
304 | 350 | #[test] |
305 | 351 | fn test_display_format() { |
306 | 352 | assert_eq!( |
|
0 commit comments