OXYGENHUB
# 232aabb5452d oxygen / vendor / iana-time-zone / src / ffi_utils.rs
19.5 KiB · Rust · last changed Strata: the cloud stores send through ureq, so every release target links 1 month ago source blame history raw
1
//! Cross platform FFI helpers.
2
3
#[cfg(any(test, target_os = "android"))]
4
use std::ffi::CStr;
5
6
/// A buffer to store the timezone name when calling the C API.
7
#[cfg(any(test, target_vendor = "apple", target_env = "ohos"))]
8
pub(crate) mod buffer {
9
    /// The longest name in the IANA time zone database is 32 ASCII characters long.
10
    pub const MAX_LEN: usize = 64;
11
12
    /// Return a buffer to store the timezone name.
13
    ///
14
    /// The buffer is used to store the timezone name when calling the C API.
15
    pub const fn tzname_buf() -> [u8; MAX_LEN] {
16
        [0; MAX_LEN]
17
    }
18
}
19
20
// The system property named 'persist.sys.timezone' contains the name of the
21
// current timezone.
22
//
23
// From https://android.googlesource.com/platform/bionic/+/gingerbread-release/libc/docs/OVERVIEW.TXT#79:
24
//
25
// > The name of the current timezone is taken from the TZ environment variable,
26
// > if defined. Otherwise, the system property named 'persist.sys.timezone' is
27
// > checked instead.
28
//
29
// TODO: Use a `c"..."` literal when MSRV is upgraded beyond 1.77.0.
30
// https://doc.rust-lang.org/edition-guide/rust-2021/c-string-literals.html
31
#[cfg(any(test, target_os = "android"))]
32
const ANDROID_TIMEZONE_PROPERTY_NAME: &[u8] = b"persist.sys.timezone\0";
33
34
/// Return a [`CStr`] to access the timezone from an Android system properties
35
/// environment.
36
#[cfg(any(test, target_os = "android"))]
37
pub(crate) fn android_timezone_property_name() -> &'static CStr {
38
    // In tests or debug mode, opt into extra runtime checks.
39
    if cfg!(any(test, debug_assertions)) {
40
        return CStr::from_bytes_with_nul(ANDROID_TIMEZONE_PROPERTY_NAME).unwrap();
41
    }
42
43
    // SAFETY: the key is NUL-terminated and there are no other NULs, this
44
    // invariant is checked in tests.
45
    unsafe { CStr::from_bytes_with_nul_unchecked(ANDROID_TIMEZONE_PROPERTY_NAME) }
46
}
47
48
#[cfg(test)]
49
mod tests {
50
    use core::mem::size_of_val;
51
    use std::ffi::CStr;
52
53
    use super::buffer::{tzname_buf, MAX_LEN};
54
    use super::{android_timezone_property_name, ANDROID_TIMEZONE_PROPERTY_NAME};
55
56
    #[test]
57
    fn test_android_timezone_property_name_is_valid_cstr() {
58
        CStr::from_bytes_with_nul(ANDROID_TIMEZONE_PROPERTY_NAME).unwrap();
59
60
        let mut invalid_property_name = ANDROID_TIMEZONE_PROPERTY_NAME.to_owned();
61
        invalid_property_name.push(b'\0');
62
        CStr::from_bytes_with_nul(&invalid_property_name).unwrap_err();
63
    }
64
65
    #[test]
66
    fn test_android_timezone_property_name_getter() {
67
        let key = android_timezone_property_name().to_bytes_with_nul();
68
        assert_eq!(key, ANDROID_TIMEZONE_PROPERTY_NAME);
69
        std::str::from_utf8(key).unwrap();
70
    }
71
72
    /// An exhaustive set of IANA timezone names for testing.
73
    ///
74
    /// Pulled from Wikipedia as of Sat March 22, 2025:
75
    ///
76
    /// - <https://en.wikipedia.org/wiki/List_of_tz_database_time_zones>
77
    /// - <https://en.wikipedia.org/w/index.php?title=List_of_tz_database_time_zones&oldid=1281103182>
78
    static KNOWN_TIMEZONE_NAMES: &[&str] = &[
79
        "Africa/Abidjan",
80
        "Africa/Accra",
81
        "Africa/Addis_Ababa",
82
        "Africa/Algiers",
83
        "Africa/Asmara",
84
        "Africa/Asmera",
85
        "Africa/Bamako",
86
        "Africa/Bangui",
87
        "Africa/Banjul",
88
        "Africa/Bissau",
89
        "Africa/Blantyre",
90
        "Africa/Brazzaville",
91
        "Africa/Bujumbura",
92
        "Africa/Cairo",
93
        "Africa/Casablanca",
94
        "Africa/Conakry",
95
        "Africa/Dakar",
96
        "Africa/Dar_es_Salaam",
97
        "Africa/Djibouti",
98
        "Africa/Douala",
99
        "Africa/El_Aaiun",
100
        "Africa/Freetown",
101
        "Africa/Gaborone",
102
        "Africa/Harare",
103
        "Africa/Johannesburg",
104
        "Africa/Juba",
105
        "Africa/Kampala",
106
        "Africa/Khartoum",
107
        "Africa/Kigali",
108
        "Africa/Libreville",
109
        "Africa/Lome",
110
        "Africa/Luanda",
111
        "Africa/Lusaka",
112
        "Africa/Malabo",
113
        "Africa/Maseru",
114
        "Africa/Mbabane",
115
        "Africa/Mogadishu",
116
        "Africa/Monrovia",
117
        "Africa/Nairobi",
118
        "Africa/Ndjamena",
119
        "Africa/Niamey",
120
        "Africa/Nouakchott",
121
        "Africa/Ouagadougou",
122
        "Africa/Porto-Novo",
123
        "Africa/Sao_Tome",
124
        "Africa/Timbuktu",
125
        "Africa/Tripoli",
126
        "Africa/Tunis",
127
        "Africa/Windhoek",
128
        "America/Anguilla",
129
        "America/Antigua",
130
        "America/Argentina/ComodRivadavia",
131
        "America/Aruba",
132
        "America/Asuncion",
133
        "America/Atka",
134
        "America/Barbados",
135
        "America/Belize",
136
        "America/Bogota",
137
        "America/Buenos_Aires",
138
        "America/Caracas",
139
        "America/Catamarca",
140
        "America/Cayenne",
141
        "America/Cayman",
142
        "America/Coral_Harbour",
143
        "America/Cordoba",
144
        "America/Costa_Rica",
145
        "America/Curacao",
146
        "America/Dominica",
147
        "America/El_Salvador",
148
        "America/Ensenada",
149
        "America/Fort_Wayne",
150
        "America/Godthab",
151
        "America/Grand_Turk",
152
        "America/Grenada",
153
        "America/Guadeloupe",
154
        "America/Guatemala",
155
        "America/Guyana",
156
        "America/Havana",
157
        "America/Indianapolis",
158
        "America/Jamaica",
159
        "America/Jujuy",
160
        "America/Knox_IN",
161
        "America/Kralendijk",
162
        "America/La_Paz",
163
        "America/Lima",
164
        "America/Louisville",
165
        "America/Lower_Princes",
166
        "America/Managua",
167
        "America/Marigot",
168
        "America/Martinique",
169
        "America/Mendoza",
170
        "America/Miquelon",
171
        "America/Montevideo",
172
        "America/Montreal",
173
        "America/Montserrat",
174
        "America/Nassau",
175
        "America/Nipigon",
176
        "America/Pangnirtung",
177
        "America/Paramaribo",
178
        "America/Port-au-Prince",
179
        "America/Port_of_Spain",
180
        "America/Porto_Acre",
181
        "America/Rainy_River",
182
        "America/Rosario",
183
        "America/Santa_Isabel",
184
        "America/Santo_Domingo",
185
        "America/Shiprock",
186
        "America/St_Barthelemy",
187
        "America/St_Kitts",
188
        "America/St_Lucia",
189
        "America/St_Thomas",
190
        "America/St_Vincent",
191
        "America/Tegucigalpa",
192
        "America/Thunder_Bay",
193
        "America/Tortola",
194
        "America/Virgin",
195
        "America/Yellowknife",
196
        "Antarctica/South_Pole",
197
        "Arctic/Longyearbyen",
198
        "Asia/Aden",
199
        "Asia/Amman",
200
        "Asia/Ashgabat",
201
        "Asia/Ashkhabad",
202
        "Asia/Baghdad",
203
        "Asia/Bahrain",
204
        "Asia/Baku",
205
        "Asia/Beirut",
206
        "Asia/Bishkek",
207
        "Asia/Brunei",
208
        "Asia/Calcutta",
209
        "Asia/Choibalsan",
210
        "Asia/Chongqing",
211
        "Asia/Chungking",
212
        "Asia/Colombo",
213
        "Asia/Dacca",
214
        "Asia/Damascus",
215
        "Asia/Dhaka",
216
        "Asia/Dili",
217
        "Asia/Dushanbe",
218
        "Asia/Harbin",
219
        "Asia/Hong_Kong",
220
        "Asia/Istanbul",
221
        "Asia/Jerusalem",
222
        "Asia/Kabul",
223
        "Asia/Karachi",
224
        "Asia/Kashgar",
225
        "Asia/Kathmandu",
226
        "Asia/Katmandu",
227
        "Asia/Kolkata",
228
        "Asia/Kuwait",
229
        "Asia/Macao",
230
        "Asia/Macau",
231
        "Asia/Manila",
232
        "Asia/Muscat",
233
        "Asia/Phnom_Penh",
234
        "Asia/Pyongyang",
235
        "Asia/Qatar",
236
        "Asia/Rangoon",
237
        "Asia/Saigon",
238
        "Asia/Seoul",
239
        "Asia/Taipei",
240
        "Asia/Tbilisi",
241
        "Asia/Tehran",
242
        "Asia/Tel_Aviv",
243
        "Asia/Thimbu",
244
        "Asia/Thimphu",
245
        "Asia/Ujung_Pandang",
246
        "Asia/Ulan_Bator",
247
        "Asia/Vientiane",
248
        "Asia/Yangon",
249
        "Asia/Yerevan",
250
        "Atlantic/Bermuda",
251
        "Atlantic/Cape_Verde",
252
        "Atlantic/Faeroe",
253
        "Atlantic/Faroe",
254
        "Atlantic/Jan_Mayen",
255
        "Atlantic/Reykjavik",
256
        "Atlantic/South_Georgia",
257
        "Atlantic/St_Helena",
258
        "Atlantic/Stanley",
259
        "Australia/ACT",
260
        "Australia/Canberra",
261
        "Australia/Currie",
262
        "Australia/LHI",
263
        "Australia/North",
264
        "Australia/NSW",
265
        "Australia/Queensland",
266
        "Australia/South",
267
        "Australia/Tasmania",
268
        "Australia/Victoria",
269
        "Australia/West",
270
        "Australia/Yancowinna",
271
        "Brazil/Acre",
272
        "Brazil/DeNoronha",
273
        "Brazil/East",
274
        "Brazil/West",
275
        "Canada/Atlantic",
276
        "Canada/Central",
277
        "Canada/Eastern",
278
        "Canada/Mountain",
279
        "Canada/Newfoundland",
280
        "Canada/Pacific",
281
        "Canada/Saskatchewan",
282
        "Canada/Yukon",
283
        "CET",
284
        "Chile/Continental",
285
        "Chile/EasterIsland",
286
        "CST6CDT",
287
        "Cuba",
288
        "EET",
289
        "Egypt",
290
        "Eire",
291
        "EST",
292
        "EST5EDT",
293
        "Etc/GMT",
294
        "Etc/GMT+0",
295
        "Etc/GMT+1",
296
        "Etc/GMT+10",
297
        "Etc/GMT+11",
298
        "Etc/GMT+12",
299
        "Etc/GMT+2",
300
        "Etc/GMT+3",
301
        "Etc/GMT+4",
302
        "Etc/GMT+5",
303
        "Etc/GMT+6",
304
        "Etc/GMT+7",
305
        "Etc/GMT+8",
306
        "Etc/GMT+9",
307
        "Etc/GMT-0",
308
        "Etc/GMT-1",
309
        "Etc/GMT-10",
310
        "Etc/GMT-11",
311
        "Etc/GMT-12",
312
        "Etc/GMT-13",
313
        "Etc/GMT-14",
314
        "Etc/GMT-2",
315
        "Etc/GMT-3",
316
        "Etc/GMT-4",
317
        "Etc/GMT-5",
318
        "Etc/GMT-6",
319
        "Etc/GMT-7",
320
        "Etc/GMT-8",
321
        "Etc/GMT-9",
322
        "Etc/GMT0",
323
        "Etc/Greenwich",
324
        "Etc/UCT",
325
        "Etc/Universal",
326
        "Etc/UTC",
327
        "Etc/Zulu",
328
        "Europe/Amsterdam",
329
        "Europe/Andorra",
330
        "Europe/Athens",
331
        "Europe/Belfast",
332
        "Europe/Belgrade",
333
        "Europe/Bratislava",
334
        "Europe/Brussels",
335
        "Europe/Bucharest",
336
        "Europe/Budapest",
337
        "Europe/Chisinau",
338
        "Europe/Copenhagen",
339
        "Europe/Dublin",
340
        "Europe/Gibraltar",
341
        "Europe/Guernsey",
342
        "Europe/Helsinki",
343
        "Europe/Isle_of_Man",
344
        "Europe/Istanbul",
345
        "Europe/Jersey",
346
        "Europe/Kiev",
347
        "Europe/Ljubljana",
348
        "Europe/London",
349
        "Europe/Luxembourg",
350
        "Europe/Malta",
351
        "Europe/Mariehamn",
352
        "Europe/Minsk",
353
        "Europe/Monaco",
354
        "Europe/Nicosia",
355
        "Europe/Oslo",
356
        "Europe/Paris",
357
        "Europe/Podgorica",
358
        "Europe/Prague",
359
        "Europe/Riga",
360
        "Europe/Rome",
361
        "Europe/San_Marino",
362
        "Europe/Sarajevo",
363
        "Europe/Skopje",
364
        "Europe/Sofia",
365
        "Europe/Stockholm",
366
        "Europe/Tallinn",
367
        "Europe/Tirane",
368
        "Europe/Tiraspol",
369
        "Europe/Uzhgorod",
370
        "Europe/Vaduz",
371
        "Europe/Vatican",
372
        "Europe/Vienna",
373
        "Europe/Vilnius",
374
        "Europe/Warsaw",
375
        "Europe/Zagreb",
376
        "Europe/Zaporozhye",
377
        "Factory",
378
        "GB",
379
        "GB-Eire",
380
        "GMT",
381
        "GMT+0",
382
        "GMT-0",
383
        "GMT0",
384
        "Greenwich",
385
        "Hongkong",
386
        "HST",
387
        "Iceland",
388
        "Indian/Antananarivo",
389
        "Indian/Chagos",
390
        "Indian/Christmas",
391
        "Indian/Cocos",
392
        "Indian/Comoro",
393
        "Indian/Kerguelen",
394
        "Indian/Mahe",
395
        "Indian/Mauritius",
396
        "Indian/Mayotte",
397
        "Indian/Reunion",
398
        "Iran",
399
        "Israel",
400
        "Jamaica",
401
        "Japan",
402
        "Kwajalein",
403
        "Libya",
404
        "MET",
405
        "Mexico/BajaNorte",
406
        "Mexico/BajaSur",
407
        "Mexico/General",
408
        "MST",
409
        "MST7MDT",
410
        "Navajo",
411
        "NZ",
412
        "NZ-CHAT",
413
        "Pacific/Apia",
414
        "Pacific/Efate",
415
        "Pacific/Enderbury",
416
        "Pacific/Fakaofo",
417
        "Pacific/Fiji",
418
        "Pacific/Funafuti",
419
        "Pacific/Guam",
420
        "Pacific/Johnston",
421
        "Pacific/Nauru",
422
        "Pacific/Niue",
423
        "Pacific/Norfolk",
424
        "Pacific/Noumea",
425
        "Pacific/Palau",
426
        "Pacific/Pitcairn",
427
        "Pacific/Ponape",
428
        "Pacific/Rarotonga",
429
        "Pacific/Saipan",
430
        "Pacific/Samoa",
431
        "Pacific/Tongatapu",
432
        "Pacific/Truk",
433
        "Pacific/Wallis",
434
        "Pacific/Yap",
435
        "Poland",
436
        "Portugal",
437
        "PRC",
438
        "PST8PDT",
439
        "ROC",
440
        "ROK",
441
        "Singapore",
442
        "Turkey",
443
        "UCT",
444
        "Universal",
445
        "US/Alaska",
446
        "US/Aleutian",
447
        "US/Arizona",
448
        "US/Central",
449
        "US/East-Indiana",
450
        "US/Eastern",
451
        "US/Hawaii",
452
        "US/Indiana-Starke",
453
        "US/Michigan",
454
        "US/Mountain",
455
        "US/Pacific",
456
        "US/Samoa",
457
        "UTC",
458
        "W-SU",
459
        "WET",
460
        "Zulu",
461
        "America/Rio_Branco",
462
        "America/Maceio",
463
        "America/Metlakatla",
464
        "America/Juneau",
465
        "America/Sitka",
466
        "America/Adak",
467
        "America/Yakutat",
468
        "America/Anchorage",
469
        "America/Nome",
470
        "America/Manaus",
471
        "America/Eirunepe",
472
        "Asia/Aqtobe",
473
        "America/Blanc-Sablon",
474
        "America/Puerto_Rico",
475
        "America/Goose_Bay",
476
        "America/Moncton",
477
        "America/Glace_Bay",
478
        "America/Halifax",
479
        "America/Noronha",
480
        "Asia/Atyrau",
481
        "Atlantic/Azores",
482
        "America/Bahia",
483
        "America/Bahia_Banderas",
484
        "America/Tijuana",
485
        "America/Mazatlan",
486
        "Asia/Hovd",
487
        "Asia/Shanghai",
488
        "Asia/Makassar",
489
        "Asia/Pontianak",
490
        "Pacific/Bougainville",
491
        "America/Fortaleza",
492
        "America/Sao_Paulo",
493
        "America/Argentina/Buenos_Aires",
494
        "Europe/Busingen",
495
        "Europe/Zurich",
496
        "America/Merida",
497
        "Atlantic/Canary",
498
        "Antarctica/Casey",
499
        "America/Argentina/Catamarca",
500
        "America/Indiana/Tell_City",
501
        "America/Indiana/Knox",
502
        "America/Menominee",
503
        "America/North_Dakota/Beulah",
504
        "America/North_Dakota/New_Salem",
505
        "America/North_Dakota/Center",
506
        "America/Rankin_Inlet",
507
        "America/Resolute",
508
        "America/Winnipeg",
509
        "America/Chicago",
510
        "Africa/Maputo",
511
        "America/Mexico_City",
512
        "Africa/Ceuta",
513
        "Pacific/Chatham",
514
        "America/Chihuahua",
515
        "America/Ojinaga",
516
        "America/Ciudad_Juarez",
517
        "Pacific/Chuuk",
518
        "America/Matamoros",
519
        "Europe/Simferopol",
520
        "Asia/Dubai",
521
        "America/Swift_Current",
522
        "America/Regina",
523
        "Antarctica/Davis",
524
        "Africa/Lubumbashi",
525
        "Africa/Kinshasa",
526
        "Antarctica/DumontDUrville",
527
        "America/Monterrey",
528
        "Pacific/Easter",
529
        "America/Indiana/Marengo",
530
        "America/Indiana/Vincennes",
531
        "America/Indiana/Indianapolis",
532
        "America/Indiana/Petersburg",
533
        "America/Indiana/Winamac",
534
        "America/Indiana/Vevay",
535
        "America/Kentucky/Louisville",
536
        "America/Kentucky/Monticello",
537
        "America/Detroit",
538
        "America/Iqaluit",
539
        "America/Toronto",
540
        "America/New_York",
541
        "America/Guayaquil",
542
        "America/Atikokan",
543
        "America/Panama",
544
        "Asia/Tokyo",
545
        "Pacific/Galapagos",
546
        "Pacific/Gambier",
547
        "Asia/Gaza",
548
        "Pacific/Tarawa",
549
        "Pacific/Honolulu",
550
        "Asia/Jakarta",
551
        "America/Argentina/Jujuy",
552
        "Indian/Maldives",
553
        "Pacific/Kosrae",
554
        "Pacific/Kwajalein",
555
        "America/Argentina/La_Rioja",
556
        "Pacific/Kiritimati",
557
        "Australia/Lord_Howe",
558
        "Antarctica/Macquarie",
559
        "Atlantic/Madeira",
560
        "Asia/Kuala_Lumpur",
561
        "Asia/Aqtau",
562
        "Pacific/Marquesas",
563
        "America/Cuiaba",
564
        "America/Campo_Grande",
565
        "Antarctica/Mawson",
566
        "America/Argentina/Mendoza",
567
        "Pacific/Pago_Pago",
568
        "Pacific/Midway",
569
        "America/Argentina/Cordoba",
570
        "America/Santiago",
571
        "Asia/Nicosia",
572
        "Europe/Berlin",
573
        "America/Nuuk",
574
        "Asia/Almaty",
575
        "Pacific/Majuro",
576
        "Asia/Ulaanbaatar",
577
        "Europe/Kyiv",
578
        "America/Edmonton",
579
        "America/Boise",
580
        "America/Inuvik",
581
        "America/Cambridge_Bay",
582
        "America/Denver",
583
        "Europe/Kaliningrad",
584
        "Europe/Kirov",
585
        "Europe/Moscow",
586
        "Europe/Volgograd",
587
        "Europe/Astrakhan",
588
        "Europe/Samara",
589
        "Europe/Saratov",
590
        "Europe/Ulyanovsk",
591
        "Asia/Yekaterinburg",
592
        "Asia/Omsk",
593
        "Asia/Barnaul",
594
        "Asia/Novokuznetsk",
595
        "Asia/Krasnoyarsk",
596
        "Asia/Novosibirsk",
597
        "Asia/Tomsk",
598
        "Asia/Irkutsk",
599
        "Asia/Yakutsk",
600
        "Asia/Khandyga",
601
        "Asia/Chita",
602
        "Asia/Vladivostok",
603
        "Asia/Ust-Nera",
604
        "Asia/Magadan",
605
        "Asia/Srednekolymsk",
606
        "Asia/Sakhalin",
607
        "Asia/Anadyr",
608
        "Asia/Kamchatka",
609
        "America/Phoenix",
610
        "America/Creston",
611
        "America/Dawson_Creek",
612
        "America/Fort_Nelson",
613
        "America/Whitehorse",
614
        "America/Dawson",
615
        "America/Danmarkshavn",
616
        "Asia/Jayapura",
617
        "Australia/Sydney",
618
        "Australia/Broken_Hill",
619
        "Pacific/Auckland",
620
        "Antarctica/McMurdo",
621
        "America/St_Johns",
622
        "Asia/Bangkok",
623
        "Asia/Famagusta",
624
        "Australia/Darwin",
625
        "America/Los_Angeles",
626
        "America/Vancouver",
627
        "Antarctica/Palmer",
628
        "Pacific/Port_Moresby",
629
        "America/Belem",
630
        "America/Santarem",
631
        "Asia/Singapore",
632
        "America/Recife",
633
        "Pacific/Kanton",
634
        "Pacific/Guadalcanal",
635
        "Pacific/Pohnpei",
636
        "Europe/Lisbon",
637
        "Asia/Qostanay",
638
        "Australia/Brisbane",
639
        "Australia/Lindeman",
640
        "America/Cancun",
641
        "Asia/Qyzylorda",
642
        "America/Punta_Arenas",
643
        "America/Porto_Velho",
644
        "America/Boa_Vista",
645
        "Antarctica/Rothera",
646
        "Asia/Kuching",
647
        "America/Argentina/Salta",
648
        "America/Argentina/San_Juan",
649
        "America/Argentina/San_Luis",
650
        "America/Argentina/Rio_Gallegos",
651
        "America/Scoresbysund",
652
        "Pacific/Tahiti",
653
        "America/Hermosillo",
654
        "Australia/Adelaide",
655
        "Asia/Ho_Chi_Minh",
656
        "Europe/Madrid",
657
        "Antarctica/Syowa",
658
        "Asia/Riyadh",
659
        "Australia/Hobart",
660
        "America/Thule",
661
        "America/Argentina/Ushuaia",
662
        "America/Araguaina",
663
        "Antarctica/Troll",
664
        "America/Argentina/Tucuman",
665
        "Asia/Tashkent",
666
        "Asia/Samarkand",
667
        "Australia/Melbourne",
668
        "Antarctica/Vostok",
669
        "Pacific/Wake",
670
        "Africa/Lagos",
671
        "Asia/Hebron",
672
        "Asia/Oral",
673
        "Australia/Eucla",
674
        "Australia/Perth",
675
        "Asia/Urumqi",
676
    ];
677
678
    #[test]
679
    fn test_tzname_buffer_fits_all_iana_names() {
680
        let buf = tzname_buf();
681
        let max_len = buf.len();
682
683
        let mut failed_tz_names = vec![];
684
685
        for &tz in KNOWN_TIMEZONE_NAMES {
686
            // Require max_len + 1 to account for an optional NUL terminator.
687
            if tz.len() >= max_len {
688
                failed_tz_names.push(tz);
689
            }
690
        }
691
692
        assert!(
693
            failed_tz_names.is_empty(),
694
            "One or more timezone names exceed the buffer length of {}. Max length of found timezone: {}\n{:?}",
695
            max_len,
696
            failed_tz_names.iter().map(|s| s.len()).max().unwrap(),
697
            failed_tz_names
698
        );
699
    }
700
701
    #[test]
702
    fn test_tzname_buffer_correct_size() {
703
        assert_eq!(
704
            MAX_LEN, 64,
705
            "Buffer length changed unexpectedly, ensure consistency with documented limit."
706
        );
707
        assert_eq!(
708
            tzname_buf().len(),
709
            MAX_LEN,
710
            "Buffer length changed unexpectedly, ensure consistency with documented limit."
711
        );
712
        assert_eq!(
713
            size_of_val(&tzname_buf()),
714
            MAX_LEN,
715
            "Buffer length changed unexpectedly, ensure consistency with documented limit."
716
        );
717
    }
718
}