Skip to content

Commit 672b038

Browse files
committed
Rewite caching in local::unix module
1 parent 02c68d6 commit 672b038

File tree

2 files changed

+303
-237
lines changed

2 files changed

+303
-237
lines changed

src/offset/local/tz_info/timezone.rs

Lines changed: 1 addition & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
//! Types related to a time zone.
22
3-
use std::fs::{self, File};
4-
use std::io::{self, Read};
5-
use std::path::{Path, PathBuf};
63
use std::{cmp::Ordering, fmt, str};
74

85
use super::rule::{AlternateTime, TransitionRule};
@@ -22,43 +19,8 @@ pub(crate) struct TimeZone {
2219
}
2320

2421
impl TimeZone {
25-
/// Returns local time zone.
26-
///
27-
/// This method in not supported on non-UNIX platforms, and returns the UTC time zone instead.
28-
pub(crate) fn local(env_tz: Option<&str>) -> Result<Self, Error> {
29-
match env_tz {
30-
Some(tz) => Self::from_posix_tz(tz),
31-
None => Self::from_posix_tz("localtime"),
32-
}
33-
}
34-
3522
/// Construct a time zone from a POSIX TZ string, as described in [the POSIX documentation of the `TZ` environment variable](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html).
36-
fn from_posix_tz(tz_string: &str) -> Result<Self, Error> {
37-
if tz_string.is_empty() {
38-
return Err(Error::InvalidTzString("empty TZ string"));
39-
}
40-
41-
if tz_string == "localtime" {
42-
return Self::from_tz_data(&fs::read("/etc/localtime")?);
43-
}
44-
45-
// attributes are not allowed on if blocks in Rust 1.38
46-
#[cfg(target_os = "android")]
47-
{
48-
if let Ok(bytes) = android_tzdata::find_tz_data(tz_string) {
49-
return Self::from_tz_data(&bytes);
50-
}
51-
}
52-
53-
let mut chars = tz_string.chars();
54-
if chars.next() == Some(':') {
55-
return Self::from_file(&mut find_tz_file(chars.as_str())?);
56-
}
57-
58-
if let Ok(mut file) = find_tz_file(tz_string) {
59-
return Self::from_file(&mut file);
60-
}
61-
23+
pub(crate) fn from_tz_string(tz_string: &str) -> Result<Self, Error> {
6224
// TZ string extensions are not allowed
6325
let tz_string = tz_string.trim_matches(|c: char| c.is_ascii_whitespace());
6426
let rule = TransitionRule::from_tz_string(tz_string.as_bytes(), false)?;
@@ -85,13 +47,6 @@ impl TimeZone {
8547
Ok(new)
8648
}
8749

88-
/// Construct a time zone from the contents of a time zone file
89-
fn from_file(file: &mut File) -> Result<Self, Error> {
90-
let mut bytes = Vec::new();
91-
file.read_to_end(&mut bytes)?;
92-
Self::from_tz_data(&bytes)
93-
}
94-
9550
/// Construct a time zone from the contents of a time zone file
9651
///
9752
/// Parse TZif data as described in [RFC 8536](https://datatracker.ietf.org/doc/html/rfc8536).
@@ -606,34 +561,6 @@ impl LocalTimeType {
606561
pub(super) const UTC: LocalTimeType = Self { ut_offset: 0, is_dst: false, name: None };
607562
}
608563

609-
/// Open the TZif file corresponding to a TZ string
610-
fn find_tz_file(path: impl AsRef<Path>) -> Result<File, Error> {
611-
// Don't check system timezone directories on non-UNIX platforms
612-
#[cfg(not(unix))]
613-
return Ok(File::open(path)?);
614-
615-
#[cfg(unix)]
616-
{
617-
let path = path.as_ref();
618-
if path.is_absolute() {
619-
return Ok(File::open(path)?);
620-
}
621-
622-
for folder in &ZONE_INFO_DIRECTORIES {
623-
if let Ok(file) = File::open(PathBuf::from(folder).join(path)) {
624-
return Ok(file);
625-
}
626-
}
627-
628-
Err(Error::Io(io::ErrorKind::NotFound.into()))
629-
}
630-
}
631-
632-
// Possible system timezone directories
633-
#[cfg(unix)]
634-
const ZONE_INFO_DIRECTORIES: [&str; 4] =
635-
["/usr/share/zoneinfo", "/share/zoneinfo", "/etc/zoneinfo", "/usr/share/lib/zoneinfo"];
636-
637564
/// Number of seconds in one week
638565
pub(crate) const SECONDS_PER_WEEK: i64 = SECONDS_PER_DAY * DAYS_PER_WEEK;
639566
/// Number of seconds in 28 days
@@ -844,34 +771,6 @@ mod tests {
844771
Ok(())
845772
}
846773

847-
#[test]
848-
fn test_time_zone_from_posix_tz() -> Result<(), Error> {
849-
#[cfg(unix)]
850-
{
851-
// if the TZ var is set, this essentially _overrides_ the
852-
// time set by the localtime symlink
853-
// so just ensure that ::local() acts as expected
854-
// in this case
855-
if let Ok(tz) = std::env::var("TZ") {
856-
let time_zone_local = TimeZone::local(Some(tz.as_str()))?;
857-
let time_zone_local_1 = TimeZone::from_posix_tz(&tz)?;
858-
assert_eq!(time_zone_local, time_zone_local_1);
859-
}
860-
861-
// `TimeZone::from_posix_tz("UTC")` will return `Error` if the environment does not have
862-
// a time zone database, like for example some docker containers.
863-
// In that case skip the test.
864-
if let Ok(time_zone_utc) = TimeZone::from_posix_tz("UTC") {
865-
assert_eq!(time_zone_utc.find_local_time_type(0)?.offset(), 0);
866-
}
867-
}
868-
869-
assert!(TimeZone::from_posix_tz("EST5EDT,0/0,J365/25").is_err());
870-
assert!(TimeZone::from_posix_tz("").is_err());
871-
872-
Ok(())
873-
}
874-
875774
#[test]
876775
fn test_leap_seconds() -> Result<(), Error> {
877776
let time_zone = TimeZone::new(

0 commit comments

Comments
 (0)