diff --git a/.lock b/.lock new file mode 100644 index 00000000..e69de29b diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/crates.js b/crates.js new file mode 100644 index 00000000..6f5a879b --- /dev/null +++ b/crates.js @@ -0,0 +1 @@ +window.ALL_CRATES = ["strftime"]; \ No newline at end of file diff --git a/help.html b/help.html new file mode 100644 index 00000000..71e406bf --- /dev/null +++ b/help.html @@ -0,0 +1 @@ +Help

Rustdoc help

Back
\ No newline at end of file diff --git a/search-index.js b/search-index.js new file mode 100644 index 00000000..8de6db73 --- /dev/null +++ b/search-index.js @@ -0,0 +1,5 @@ +var searchIndex = JSON.parse('{\ +"strftime":{"doc":"This crate provides a Ruby 3.1.2 compatible strftime …","t":"RENNNNNNINLLAAKKKALLLLLLKLAKKKKKLAKKLLLLKKFFFFF","n":["ASCTIME_FORMAT_STRING","Error","FmtError","FormattedStringTooLarge","InvalidFormatString","InvalidTime","IoError","OutOfMemory","Time","WriteZero","borrow","borrow_mut","buffered","bytes","day","day_of_week","day_of_year","fmt","fmt","fmt","from","from","from","from","hour","into","io","is_utc","minute","month","nanoseconds","second","source","string","time_zone","to_int","to_string","try_from","try_into","type_id","utc_offset","year","strftime","strftime","strftime","strftime","strftime"],"q":[[0,"strftime"],[42,"strftime::buffered"],[43,"strftime::bytes"],[44,"strftime::fmt"],[45,"strftime::io"],[46,"strftime::string"],[47,"core::fmt"],[48,"core::fmt"],[49,"alloc::collections"],[50,"core::error"],[51,"core::option"],[52,"alloc::string"],[53,"core::result"],[54,"core::any"],[55,"alloc::vec"],[56,"core::fmt"]],"d":["Format string used by Ruby Time#asctime method.","Error type returned by the strftime functions.","Formatting error, corresponding to core::fmt::Error.","Formatted string is too large and could cause an …","Provided format string is ended by an unterminated format …","Provided time implementation returns invalid values.","An I/O error has occurred in io::strftime.","An allocation failure has occurred in either …","Common methods needed for formatting time.","Provided buffer for the buffered::strftime function is too …","","","Provides a strftime implementation using a format string …","Provides a strftime implementation using a format string …","Returns the day of the month in 1..=31 for time.","Returns an integer representing the day of the week in …","Returns an integer representing the day of the year in …","Provides a strftime implementation using a UTF-8 format …","","","Returns the argument unchanged.","","","","Returns the hour of the day in 0..=23 for time.","Calls U::from(self).","Provides a strftime implementation using a format string …","Returns true if the time zone is UTC.","Returns the minute of the hour in 0..=59 for time.","Returns the month of the year in 1..=12 for time.","Returns the number of nanoseconds in 0..=999_999_999 for …","Returns the second of the minute in 0..=60 for time.","","Provides a strftime implementation using a UTF-8 format …","Returns the name of the time zone as a string.","Returns the number of seconds as a signed integer since …","","","","","Returns the offset in seconds between the timezone of time …","Returns the year for time (including the century).","Format a time implementation with the specified format …","Format a time implementation with the specified format …","Format a time implementation with the specified UTF-8 …","Format a time implementation with the specified format …","Format a time implementation with the specified UTF-8 …"],"i":[0,0,3,3,3,3,3,3,0,3,3,3,0,0,20,20,20,0,3,3,3,3,3,3,20,3,0,20,20,20,20,20,3,0,20,20,3,3,3,3,20,20,0,0,0,0,0],"f":[0,0,0,0,0,0,0,0,0,0,[-1,-2,[],[]],[-1,-2,[],[]],0,0,[-1,1,[]],[-1,1,[]],[-1,2,[]],0,[[3,4],5],[[3,4],5],[-1,-1,[]],[6,3],[7,3],[8,3],[-1,1,[]],[-1,-2,[],[]],0,[-1,9,[]],[-1,1,[]],[-1,1,[]],[-1,10,[]],[-1,1,[]],[3,[[12,[11]]]],0,[-1,13,[]],[-1,14,[]],[-1,15,[]],[-1,[[16,[-2]]],[],[]],[-1,[[16,[-2]]],[],[]],[-1,17,[]],[-1,18,[]],[-1,18,[]],[[-1,[19,[1]],[19,[1]]],[[16,[[19,[1]],3]]],20],[[-1,[19,[1]]],[[16,[[21,[1]],3]]],20],[[-1,13,22],[[16,[23,3]]],20],[[-1,[19,[1]],24],[[16,[23,3]]],20],[[-1,13],[[16,[15,3]]],20]],"c":[],"p":[[15,"u8"],[15,"u16"],[4,"Error",0],[3,"Formatter",47],[6,"Result",47],[3,"Error",47],[3,"Error",48],[3,"TryReserveError",49],[15,"bool"],[15,"u32"],[8,"Error",50],[4,"Option",51],[15,"str"],[15,"i64"],[3,"String",52],[4,"Result",53],[3,"TypeId",54],[15,"i32"],[15,"slice"],[8,"Time",0],[3,"Vec",55],[8,"Write",47],[15,"tuple"],[8,"Write",56]],"b":[[18,"impl-Debug-for-Error"],[19,"impl-Display-for-Error"],[21,"impl-From%3CError%3E-for-Error"],[22,"impl-From%3CError%3E-for-Error"],[23,"impl-From%3CTryReserveError%3E-for-Error"]]}\ +}'); +if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)}; +if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex}; diff --git a/settings.html b/settings.html new file mode 100644 index 00000000..9d10e550 --- /dev/null +++ b/settings.html @@ -0,0 +1 @@ +Settings

Rustdoc settings

Back
\ No newline at end of file diff --git a/src-files.js b/src-files.js new file mode 100644 index 00000000..316570d9 --- /dev/null +++ b/src-files.js @@ -0,0 +1,4 @@ +var srcIndex = JSON.parse('{\ +"strftime":["",[["format",[],["assert.rs","check.rs","mod.rs","utils.rs","week.rs","write.rs"]]],["lib.rs"]]\ +}'); +createSrcSidebar(); diff --git a/src/strftime/format/assert.rs.html b/src/strftime/format/assert.rs.html new file mode 100644 index 00000000..6e881d5b --- /dev/null +++ b/src/strftime/format/assert.rs.html @@ -0,0 +1,189 @@ +assert.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+
//! Compile-time assert functions.
+
+/// Helper macro for implementing asserts.
+macro_rules! assert_sorted_by_key {
+    ($s:expr, $f:expr) => {{
+        let mut i = 0;
+        while i + 1 < $s.len() {
+            assert!(*$f(&$s[i]) < *$f(&$s[i + 1]));
+            i += 1;
+        }
+        $s
+    }};
+}
+
+/// Returns the first element of a tuple.
+const fn elem_0<T>(x: &(u8, T)) -> &u8 {
+    &x.0
+}
+
+/// Asserts that a slice is sorted and has no duplicates.
+pub(crate) const fn assert_sorted(s: &[u8]) -> &[u8] {
+    assert_sorted_by_key!(s, core::convert::identity)
+}
+
+/// Asserts that a slice is sorted by its first element and has no duplicates.
+pub(crate) const fn assert_sorted_elem_0<T>(s: &[(u8, T)]) -> &[(u8, T)] {
+    assert_sorted_by_key!(s, elem_0)
+}
+
+/// Asserts that converting the first input to uppercase yields the second input.
+#[allow(dead_code)]
+pub(crate) const fn assert_to_ascii_uppercase(table: &[&str], upper_table: &[&str]) {
+    assert!(table.len() == upper_table.len());
+
+    let mut index = 0;
+    while index < table.len() {
+        let (s, upper_s) = (table[index].as_bytes(), upper_table[index].as_bytes());
+        assert!(s.len() == upper_s.len());
+
+        let mut i = 0;
+        while i < s.len() {
+            assert!(s[i].is_ascii());
+            assert!(upper_s[i].is_ascii());
+            assert!(upper_s[i] == s[i].to_ascii_uppercase());
+            i += 1;
+        }
+
+        index += 1;
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_assert_sorted() {
+        assert_sorted(&[1, 2, 3]);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_assert_sorted_invalid() {
+        assert_sorted(&[1, 3, 2]);
+    }
+
+    #[test]
+    fn test_assert_sorted_elem_0() {
+        assert_sorted_elem_0(&[(1, 3), (2, 2), (3, 1)]);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_assert_sorted_elem_0_invalid() {
+        assert_sorted_elem_0(&[(1, 3), (3, 2), (2, 1)]);
+    }
+
+    #[test]
+    fn test_assert_to_ascii_uppercase() {
+        assert_to_ascii_uppercase(&["aaa"], &["AAA"]);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_assert_to_ascii_uppercase_invalid() {
+        assert_to_ascii_uppercase(&["aaa"], &["AaA"]);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_assert_to_ascii_uppercase_invalid_ascii() {
+        assert_to_ascii_uppercase(&["€"], &["€"]);
+    }
+}
+
\ No newline at end of file diff --git a/src/strftime/format/check.rs.html b/src/strftime/format/check.rs.html new file mode 100644 index 00000000..156bba86 --- /dev/null +++ b/src/strftime/format/check.rs.html @@ -0,0 +1,317 @@ +check.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+
//! Checks for a time implementation.
+
+use crate::{Error, Time};
+
+/// Wrapper trait for validating a time implementation.
+pub(crate) trait CheckedTime {
+    /// No checks.
+    fn year(&self) -> i32;
+    /// Checks if the month is in `1..=12`.
+    fn month(&self) -> Result<u8, Error>;
+    /// Checks if the day of the month is in `1..=31`.
+    fn day(&self) -> Result<u8, Error>;
+    /// Checks if the hour of the day is in `0..=23`.
+    fn hour(&self) -> Result<u8, Error>;
+    /// Checks if the minute of the hour is in `0..=59`.
+    fn minute(&self) -> Result<u8, Error>;
+    /// Checks if the second of the minute is in `0..=60`.
+    fn second(&self) -> Result<u8, Error>;
+    /// Checks if the number of nanoseconds is in `0..=999_999_999`.
+    fn nanoseconds(&self) -> Result<u32, Error>;
+    /// Checks if the day of the week is in `0..=6`.
+    fn day_of_week(&self) -> Result<u8, Error>;
+    /// Checks if the day of the year is in `1..=366`.
+    fn day_of_year(&self) -> Result<u16, Error>;
+    /// No checks.
+    fn to_int(&self) -> i64;
+    /// No checks.
+    fn is_utc(&self) -> bool;
+    /// No checks.
+    fn utc_offset(&self) -> i32;
+    /// Checks if the name of the time zone is valid ASCII.
+    fn time_zone(&self) -> Result<&str, Error>;
+}
+
+impl<T: Time> CheckedTime for T {
+    fn year(&self) -> i32 {
+        self.year()
+    }
+
+    fn month(&self) -> Result<u8, Error> {
+        match self.month() {
+            month @ 1..=12 => Ok(month),
+            _ => Err(Error::InvalidTime),
+        }
+    }
+
+    fn day(&self) -> Result<u8, Error> {
+        match self.day() {
+            day @ 1..=31 => Ok(day),
+            _ => Err(Error::InvalidTime),
+        }
+    }
+
+    fn hour(&self) -> Result<u8, Error> {
+        match self.hour() {
+            hour @ 0..=23 => Ok(hour),
+            _ => Err(Error::InvalidTime),
+        }
+    }
+
+    fn minute(&self) -> Result<u8, Error> {
+        match self.minute() {
+            minute @ 0..=59 => Ok(minute),
+            _ => Err(Error::InvalidTime),
+        }
+    }
+
+    fn second(&self) -> Result<u8, Error> {
+        match self.second() {
+            second @ 0..=60 => Ok(second),
+            _ => Err(Error::InvalidTime),
+        }
+    }
+
+    fn nanoseconds(&self) -> Result<u32, Error> {
+        match self.nanoseconds() {
+            nanoseconds @ 0..=999_999_999 => Ok(nanoseconds),
+            _ => Err(Error::InvalidTime),
+        }
+    }
+
+    fn day_of_week(&self) -> Result<u8, Error> {
+        match self.day_of_week() {
+            day_of_week @ 0..=6 => Ok(day_of_week),
+            _ => Err(Error::InvalidTime),
+        }
+    }
+
+    fn day_of_year(&self) -> Result<u16, Error> {
+        match self.day_of_year() {
+            day_of_year @ 1..=366 => Ok(day_of_year),
+            _ => Err(Error::InvalidTime),
+        }
+    }
+
+    fn to_int(&self) -> i64 {
+        self.to_int()
+    }
+
+    fn is_utc(&self) -> bool {
+        self.is_utc()
+    }
+
+    fn utc_offset(&self) -> i32 {
+        self.utc_offset()
+    }
+
+    fn time_zone(&self) -> Result<&str, Error> {
+        match self.time_zone() {
+            time_zone if time_zone.is_ascii() => Ok(time_zone),
+            _ => Err(Error::InvalidTime),
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    include!("../mock.rs.in");
+
+    fn check<T>(ok: bool, result: &Result<T, Error>) {
+        if ok {
+            assert!(result.is_ok());
+        } else {
+            assert!(matches!(result, Err(Error::InvalidTime)));
+        }
+    }
+
+    #[test]
+    fn test_checked_time() {
+        #[rustfmt::skip]
+        let times = [
+            MockTime::new(1970, 1, 1, 0, 0, 0, 0, 4, 1, 0, false, 0, ""),
+            MockTime::new(1970, 0, 0, 99, 99, 99, 1_000_000_000, 9, 999, 0, false, 0, "€"),
+        ];
+
+        check(true, &CheckedTime::month(&times[0]));
+        check(true, &CheckedTime::day(&times[0]));
+        check(true, &CheckedTime::hour(&times[0]));
+        check(true, &CheckedTime::minute(&times[0]));
+        check(true, &CheckedTime::second(&times[0]));
+        check(true, &CheckedTime::nanoseconds(&times[0]));
+        check(true, &CheckedTime::day_of_week(&times[0]));
+        check(true, &CheckedTime::day_of_year(&times[0]));
+        check(true, &CheckedTime::time_zone(&times[0]));
+
+        check(false, &CheckedTime::month(&times[1]));
+        check(false, &CheckedTime::day(&times[1]));
+        check(false, &CheckedTime::hour(&times[1]));
+        check(false, &CheckedTime::minute(&times[1]));
+        check(false, &CheckedTime::second(&times[1]));
+        check(false, &CheckedTime::nanoseconds(&times[1]));
+        check(false, &CheckedTime::day_of_week(&times[1]));
+        check(false, &CheckedTime::day_of_year(&times[1]));
+        check(false, &CheckedTime::time_zone(&times[1]));
+    }
+}
+
\ No newline at end of file diff --git a/src/strftime/format/mod.rs.html b/src/strftime/format/mod.rs.html new file mode 100644 index 00000000..e8353bba --- /dev/null +++ b/src/strftime/format/mod.rs.html @@ -0,0 +1,2075 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+
//! Module containing the formatting logic.
+
+mod assert;
+mod check;
+mod utils;
+mod week;
+mod write;
+
+use core::fmt;
+use core::num::IntErrorKind;
+use core::str;
+
+use crate::Error;
+use assert::{assert_sorted, assert_sorted_elem_0, assert_to_ascii_uppercase};
+use check::CheckedTime;
+use utils::{Cursor, SizeLimiter};
+use week::{iso_8601_year_and_week_number, week_number, WeekStart};
+use write::Write;
+
+pub(crate) use write::FmtWrite;
+#[cfg(feature = "std")]
+pub(crate) use write::IoWrite;
+
+/// Alias to a `c_int`.
+#[cfg(feature = "std")]
+type Int = std::os::raw::c_int;
+/// Fallback alias to a `c_int`.
+#[cfg(not(feature = "std"))]
+type Int = i32;
+
+/// List of weekday names.
+const DAYS: [&str; 7] = [
+    "Sunday",
+    "Monday",
+    "Tuesday",
+    "Wednesday",
+    "Thursday",
+    "Friday",
+    "Saturday",
+];
+
+/// List of uppercase weekday names.
+const DAYS_UPPER: [&str; 7] = [
+    "SUNDAY",
+    "MONDAY",
+    "TUESDAY",
+    "WEDNESDAY",
+    "THURSDAY",
+    "FRIDAY",
+    "SATURDAY",
+];
+
+/// List of month names.
+const MONTHS: [&str; 12] = [
+    "January",
+    "February",
+    "March",
+    "April",
+    "May",
+    "June",
+    "July",
+    "August",
+    "September",
+    "October",
+    "November",
+    "December",
+];
+
+/// List of uppercase month names.
+const MONTHS_UPPER: [&str; 12] = [
+    "JANUARY",
+    "FEBRUARY",
+    "MARCH",
+    "APRIL",
+    "MAY",
+    "JUNE",
+    "JULY",
+    "AUGUST",
+    "SEPTEMBER",
+    "OCTOBER",
+    "NOVEMBER",
+    "DECEMBER",
+];
+
+// Check day and month tables
+const _: () = {
+    assert_to_ascii_uppercase(&DAYS, &DAYS_UPPER);
+    assert_to_ascii_uppercase(&MONTHS, &MONTHS_UPPER);
+};
+
+/// Formatting flag.
+#[repr(u8)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+enum Flag {
+    /// Use left padding, removing all other padding options in most cases.
+    LeftPadding = 1 << 0,
+    /// Change case for a string value.
+    ChangeCase = 1 << 1,
+    /// Convert a string value to uppercase.
+    UpperCase = 1 << 2,
+}
+
+/// Combination of formatting flags.
+#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
+struct Flags(u8);
+
+impl Flags {
+    /// Checks if a flag is set.
+    #[must_use]
+    fn contains(self, flag: Flag) -> bool {
+        let flag = flag as u8;
+        (self.0 & flag) == flag
+    }
+
+    /// Sets a flag.
+    fn set(&mut self, flag: Flag) {
+        self.0 |= flag as u8;
+    }
+
+    /// Checks if one of the case flags is set.
+    #[must_use]
+    fn has_change_or_upper_case(self) -> bool {
+        let flags = Flag::ChangeCase as u8 | Flag::UpperCase as u8;
+        self.0 & flags != 0
+    }
+}
+
+/// Padding method.
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+enum Padding {
+    /// Left padding.
+    Left,
+    /// Padding with spaces.
+    Spaces,
+    /// Padding with zeros.
+    Zeros,
+}
+
+/// Formatting specifier.
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+enum Spec {
+    /// `"%Y"`: Year with century if provided, zero-padded to at least 4 digits
+    /// plus the possible negative sign.
+    Year4Digits,
+    /// `"%C"`: `Year / 100` using Euclidean division, zero-padded to at least 2
+    /// digits.
+    YearDiv100,
+    /// `"%y"`: `Year % 100` in `00..=99`, using Euclidean remainder, zero-padded
+    /// to 2 digits.
+    YearRem100,
+    /// `"%m"`: Month of the year in `01..=12`, zero-padded to 2 digits.
+    Month,
+    /// `"%B"`: Locale independent full month name.
+    MonthName,
+    /// `"%b"` and `"%h"`: Locale independent abbreviated month name, using the
+    /// first 3 letters.
+    MonthNameAbbr,
+    /// `"%d"`: Day of the month in `01..=31`, zero-padded to 2 digits.
+    MonthDayZero,
+    /// `"%e"`: Day of the month in ` 1..=31`, blank-padded to 2 digits.
+    MonthDaySpace,
+    /// `"%j"`: Day of the year in `001..=366`, zero-padded to 3 digits.
+    YearDay,
+    /// `"%H"`: Hour of the day (24-hour clock) in `00..=23`, zero-padded to 2
+    /// digits.
+    Hour24hZero,
+    /// `"%k"`: Hour of the day (24-hour clock) in ` 0..=23`, blank-padded to 2
+    /// digits.
+    Hour24hSpace,
+    /// `"%I"`: Hour of the day (12-hour clock) in `01..=12`, zero-padded to 2
+    /// digits.
+    Hour12hZero,
+    /// `"%l"`: Hour of the day (12-hour clock) in ` 1..=12`, blank-padded to 2
+    /// digits.
+    Hour12hSpace,
+    /// `"%P"`: Lowercase meridian indicator (`"am"` or `"pm"`).
+    MeridianLower,
+    /// `"%p"`: Uppercase meridian indicator (`"AM"` or `"PM"`).
+    MeridianUpper,
+    /// `"%M"`: Minute of the hour in `00..=59`, zero-padded to 2 digits.
+    Minute,
+    /// `"%S"`: Second of the minute in `00..=60`, zero-padded to 2 digits.
+    Second,
+    /// `"%L"`: Truncated fractional seconds digits, with 3 digits by default.
+    /// Number of digits is specified by the width field.
+    MilliSecond,
+    /// `"%N"`: Truncated fractional seconds digits, with 9 digits by default.
+    /// Number of digits is specified by the width field.
+    FractionalSecond,
+    /// `"%z"`: Zero-padded signed time zone UTC hour and minute offsets
+    /// (`+hhmm`).
+    TimeZoneOffsetHourMinute,
+    /// `"%:z"`: Zero-padded signed time zone UTC hour and minute offsets with
+    /// colons (`+hh:mm`).
+    TimeZoneOffsetHourMinuteColon,
+    /// `"%::z"`: Zero-padded signed time zone UTC hour, minute and second
+    /// offsets with colons (`+hh:mm:ss`).
+    TimeZoneOffsetHourMinuteSecondColon,
+    /// `"%:::z"`: Zero-padded signed time zone UTC hour offset, with optional
+    /// minute and second offsets with colons (`+hh[:mm[:ss]]`).
+    TimeZoneOffsetColonMinimal,
+    /// `"%Z"`: Platform-dependent abbreviated time zone name.
+    TimeZoneName,
+    /// `"%A"`: Locale independent full weekday name.
+    WeekDayName,
+    /// `"%a"`: Locale independent abbreviated weekday name, using the first 3
+    /// letters.
+    WeekDayNameAbbr,
+    /// `"%u"`: Day of the week from Monday in `1..=7`, zero-padded to 1 digit.
+    WeekDayFrom1,
+    /// `"%w"`: Day of the week from Sunday in `0..=6`, zero-padded to 1 digit.
+    WeekDayFrom0,
+    /// `"%G"`: Same as `%Y`, but using the ISO 8601 week-based year.
+    YearIso8601,
+    /// `"%g"`: Same as `%y`, but using the ISO 8601 week-based year.
+    YearIso8601Rem100,
+    /// `"%V"`: ISO 8601 week number in `01..=53`, zero-padded to 2 digits.
+    WeekNumberIso8601,
+    /// `"%U"`: Week number from Sunday in `00..=53`, zero-padded to 2 digits.
+    /// The week `1` starts with the first Sunday of the year.
+    WeekNumberFromSunday,
+    /// `"%W"`: Week number from Monday in `00..=53`, zero-padded to 2 digits.
+    /// The week `1` starts with the first Monday of the year.
+    WeekNumberFromMonday,
+    /// `"%s"`: Number of seconds since `1970-01-01 00:00:00 UTC`, zero-padded
+    /// to at least 1 digit.
+    SecondsSinceEpoch,
+    /// `"%n"`: Newline character `'\n'`.
+    Newline,
+    /// `"%t"`: Tab character `'\t'`.
+    Tabulation,
+    /// `"%%"`: Literal `'%'` character.
+    Percent,
+    /// `"%c"`: Date and time, equivalent to `"%a %b %e %H:%M:%S %Y"`.
+    CombinationDateTime,
+    /// `"%D"` and `"%x"`: Date, equivalent to `"%m/%d/%y"`.
+    CombinationDate,
+    /// `"%F"`: ISO 8601 date, equivalent to `"%Y-%m-%d"`.
+    CombinationIso8601,
+    /// `"%v"`: VMS date, equivalent to `"%e-%^b-%4Y"`.
+    CombinationVmsDate,
+    /// `"%r"`: 12-hour time, equivalent to `"%I:%M:%S %p"`.
+    CombinationTime12h,
+    /// `"%R"`: 24-hour time without seconds, equivalent to `"%H:%M"`.
+    CombinationHourMinute24h,
+    /// `"%T"` and `"%X"`: 24-hour time, equivalent to `"%H:%M:%S"`.
+    CombinationTime24h,
+}
+
+/// UTC offset parts.
+#[derive(Debug)]
+struct UtcOffset {
+    /// Signed hour.
+    hour: f64,
+    /// Minute.
+    minute: u32,
+    /// Second.
+    second: u32,
+}
+
+impl UtcOffset {
+    /// Construct a new `UtcOffset`.
+    fn new(hour: f64, minute: u32, second: u32) -> Self {
+        Self {
+            hour,
+            minute,
+            second,
+        }
+    }
+}
+
+/// Formatting directive.
+#[derive(Debug)]
+struct Piece {
+    /// Optional width.
+    width: Option<usize>,
+    /// Padding method.
+    padding: Padding,
+    /// Combination of formatting flags.
+    flags: Flags,
+    /// Formatting specifier.
+    spec: Spec,
+}
+
+impl Piece {
+    /// Construct a new `Piece`.
+    fn new(width: Option<usize>, padding: Padding, flags: Flags, spec: Spec) -> Self {
+        Self {
+            width,
+            padding,
+            flags,
+            spec,
+        }
+    }
+
+    /// Format a numerical value, padding with zeros by default.
+    fn format_num_zeros(
+        &self,
+        f: &mut SizeLimiter<'_>,
+        value: impl fmt::Display,
+        default_width: usize,
+    ) -> Result<(), Error> {
+        if self.flags.contains(Flag::LeftPadding) {
+            write!(f, "{value}")
+        } else if self.padding == Padding::Spaces {
+            let width = self.width.unwrap_or(default_width);
+            write!(f, "{value: >width$}")
+        } else {
+            let width = self.width.unwrap_or(default_width);
+            write!(f, "{value:0width$}")
+        }
+    }
+
+    /// Format a numerical value, padding with spaces by default.
+    fn format_num_spaces(
+        &self,
+        f: &mut SizeLimiter<'_>,
+        value: impl fmt::Display,
+        default_width: usize,
+    ) -> Result<(), Error> {
+        if self.flags.contains(Flag::LeftPadding) {
+            write!(f, "{value}")
+        } else if self.padding == Padding::Zeros {
+            let width = self.width.unwrap_or(default_width);
+            write!(f, "{value:0width$}")
+        } else {
+            let width = self.width.unwrap_or(default_width);
+            write!(f, "{value: >width$}")
+        }
+    }
+
+    /// Format nanoseconds with the specified precision.
+    #[allow(clippy::uninlined_format_args)] // for readability and symmetry between if branches
+    fn format_nanoseconds(
+        &self,
+        f: &mut SizeLimiter<'_>,
+        nanoseconds: u32,
+        default_width: usize,
+    ) -> Result<(), Error> {
+        let width = self.width.unwrap_or(default_width);
+
+        if width <= 9 {
+            let value = nanoseconds / 10u32.pow(9 - width as u32);
+            write!(f, "{value:0n$}", n = width)
+        } else {
+            write!(f, "{nanoseconds:09}{:0n$}", 0, n = width - 9)
+        }
+    }
+
+    /// Format a string value.
+    fn format_string(&self, f: &mut SizeLimiter<'_>, s: &str) -> Result<(), Error> {
+        match self.width {
+            None => write!(f, "{s}"),
+            Some(width) => {
+                if self.flags.contains(Flag::LeftPadding) {
+                    write!(f, "{s}")
+                } else if self.padding == Padding::Zeros {
+                    write!(f, "{s:0>width$}")
+                } else {
+                    write!(f, "{s: >width$}")
+                }
+            }
+        }
+    }
+
+    /// Write padding separately.
+    fn write_padding(&self, f: &mut SizeLimiter<'_>, min_width: usize) -> Result<(), Error> {
+        if let Some(width) = self.width {
+            let n = width.saturating_sub(min_width);
+
+            match self.padding {
+                Padding::Zeros => write!(f, "{:0>n$}", "")?,
+                _ => write!(f, "{: >n$}", "")?,
+            };
+        }
+        Ok(())
+    }
+
+    /// Compute UTC offset parts for the `%z` specifier.
+    fn compute_offset_parts(&self, time: &impl CheckedTime) -> UtcOffset {
+        let utc_offset = time.utc_offset();
+        let utc_offset_abs = utc_offset.unsigned_abs();
+
+        // UTC is represented as "-00:00" if the '-' flag is set
+        let sign = if utc_offset < 0 || time.is_utc() && self.flags.contains(Flag::LeftPadding) {
+            -1.0
+        } else {
+            1.0
+        };
+
+        // Convert to `f64` to have signed zero
+        let hour = sign * f64::from(utc_offset_abs / 3600);
+        let minute = (utc_offset_abs / 60) % 60;
+        let second = utc_offset_abs % 60;
+
+        UtcOffset::new(hour, minute, second)
+    }
+
+    /// Compute hour padding for the `%z` specifier.
+    fn hour_padding(&self, min_width: usize) -> usize {
+        const MIN_PADDING: usize = "+hh".len();
+
+        match self.width {
+            Some(width) => width.saturating_sub(min_width) + MIN_PADDING,
+            None => MIN_PADDING,
+        }
+    }
+
+    /// Write the time zone UTC offset as `"+hh"`.
+    fn write_offset_hh(
+        &self,
+        f: &mut SizeLimiter<'_>,
+        utc_offset: &UtcOffset,
+    ) -> Result<(), Error> {
+        let hour = utc_offset.hour;
+        let n = self.hour_padding("+hh".len());
+
+        match self.padding {
+            Padding::Spaces => write!(f, "{hour: >+n$.0}"),
+            _ => write!(f, "{hour:+0n$.0}"),
+        }
+    }
+
+    /// Write the time zone UTC offset as `"+hhmm"`.
+    fn write_offset_hhmm(
+        &self,
+        f: &mut SizeLimiter<'_>,
+        utc_offset: &UtcOffset,
+    ) -> Result<(), Error> {
+        let UtcOffset { hour, minute, .. } = utc_offset;
+        let n = self.hour_padding("+hhmm".len());
+
+        match self.padding {
+            Padding::Spaces => write!(f, "{hour: >+n$.0}{minute:02}"),
+            _ => write!(f, "{hour:+0n$.0}{minute:02}"),
+        }
+    }
+
+    /// Write the time zone UTC offset as `"+hh:mm"`.
+    fn write_offset_hh_mm(
+        &self,
+        f: &mut SizeLimiter<'_>,
+        utc_offset: &UtcOffset,
+    ) -> Result<(), Error> {
+        let UtcOffset { hour, minute, .. } = utc_offset;
+        let n = self.hour_padding("+hh:mm".len());
+
+        match self.padding {
+            Padding::Spaces => write!(f, "{hour: >+n$.0}:{minute:02}"),
+            _ => write!(f, "{hour:+0n$.0}:{minute:02}"),
+        }
+    }
+
+    /// Write the time zone UTC offset as `"+hh:mm:ss"`.
+    fn write_offset_hh_mm_ss(
+        &self,
+        f: &mut SizeLimiter<'_>,
+        utc_offset: &UtcOffset,
+    ) -> Result<(), Error> {
+        let UtcOffset {
+            hour,
+            minute,
+            second,
+        } = utc_offset;
+
+        let n = self.hour_padding("+hh:mm:ss".len());
+
+        match self.padding {
+            Padding::Spaces => write!(f, "{hour: >+n$.0}:{minute:02}:{second:02}"),
+            _ => write!(f, "{hour:+0n$.0}:{minute:02}:{second:02}"),
+        }
+    }
+
+    /// Format time using the formatting directive.
+    #[allow(clippy::too_many_lines)]
+    fn fmt(&self, f: &mut SizeLimiter<'_>, time: &impl CheckedTime) -> Result<(), Error> {
+        match self.spec {
+            Spec::Year4Digits => {
+                let year = time.year();
+                let default_width = if year < 0 { 5 } else { 4 };
+                self.format_num_zeros(f, year, default_width)
+            }
+            Spec::YearDiv100 => self.format_num_zeros(f, time.year().div_euclid(100), 2),
+            Spec::YearRem100 => self.format_num_zeros(f, time.year().rem_euclid(100), 2),
+            Spec::Month => self.format_num_zeros(f, time.month()?, 2),
+            Spec::MonthName => {
+                let index = (time.month()? - 1) as usize;
+                if self.flags.has_change_or_upper_case() {
+                    self.format_string(f, MONTHS_UPPER[index])
+                } else {
+                    self.format_string(f, MONTHS[index])
+                }
+            }
+            Spec::MonthNameAbbr => {
+                let index = (time.month()? - 1) as usize;
+                if self.flags.has_change_or_upper_case() {
+                    self.format_string(f, &MONTHS_UPPER[index][..3])
+                } else {
+                    self.format_string(f, &MONTHS[index][..3])
+                }
+            }
+            Spec::MonthDayZero => self.format_num_zeros(f, time.day()?, 2),
+            Spec::MonthDaySpace => self.format_num_spaces(f, time.day()?, 2),
+            Spec::YearDay => self.format_num_zeros(f, time.day_of_year()?, 3),
+            Spec::Hour24hZero => self.format_num_zeros(f, time.hour()?, 2),
+            Spec::Hour24hSpace => self.format_num_spaces(f, time.hour()?, 2),
+            Spec::Hour12hZero => {
+                let hour = time.hour()? % 12;
+                let hour = if hour == 0 { 12 } else { hour };
+                self.format_num_zeros(f, hour, 2)
+            }
+            Spec::Hour12hSpace => {
+                let hour = time.hour()? % 12;
+                let hour = if hour == 0 { 12 } else { hour };
+                self.format_num_spaces(f, hour, 2)
+            }
+            Spec::MeridianLower => {
+                let (am, pm) = if self.flags.has_change_or_upper_case() {
+                    ("AM", "PM")
+                } else {
+                    ("am", "pm")
+                };
+                let meridian = if time.hour()? < 12 { am } else { pm };
+                self.format_string(f, meridian)
+            }
+            Spec::MeridianUpper => {
+                let (am, pm) = if self.flags.contains(Flag::ChangeCase) {
+                    ("am", "pm")
+                } else {
+                    ("AM", "PM")
+                };
+                let meridian = if time.hour()? < 12 { am } else { pm };
+                self.format_string(f, meridian)
+            }
+            Spec::Minute => self.format_num_zeros(f, time.minute()?, 2),
+            Spec::Second => self.format_num_zeros(f, time.second()?, 2),
+            Spec::MilliSecond => self.format_nanoseconds(f, time.nanoseconds()?, 3),
+            Spec::FractionalSecond => self.format_nanoseconds(f, time.nanoseconds()?, 9),
+            Spec::TimeZoneOffsetHourMinute => {
+                self.write_offset_hhmm(f, &self.compute_offset_parts(time))
+            }
+            Spec::TimeZoneOffsetHourMinuteColon => {
+                self.write_offset_hh_mm(f, &self.compute_offset_parts(time))
+            }
+            Spec::TimeZoneOffsetHourMinuteSecondColon => {
+                self.write_offset_hh_mm_ss(f, &self.compute_offset_parts(time))
+            }
+            Spec::TimeZoneOffsetColonMinimal => {
+                let utc_offset = self.compute_offset_parts(time);
+
+                if utc_offset.second != 0 {
+                    self.write_offset_hh_mm_ss(f, &utc_offset)
+                } else if utc_offset.minute != 0 {
+                    self.write_offset_hh_mm(f, &utc_offset)
+                } else {
+                    self.write_offset_hh(f, &utc_offset)
+                }
+            }
+            Spec::TimeZoneName => {
+                let tz_name = time.time_zone()?;
+                if !tz_name.is_empty() {
+                    if !self.flags.contains(Flag::LeftPadding) {
+                        self.write_padding(f, tz_name.len())?;
+                    }
+
+                    // The time zone name is guaranteed to be ASCII at this point.
+                    let convert: fn(&u8) -> u8 = if self.flags.contains(Flag::ChangeCase) {
+                        u8::to_ascii_lowercase
+                    } else if self.flags.contains(Flag::UpperCase) {
+                        u8::to_ascii_uppercase
+                    } else {
+                        |&x| x
+                    };
+
+                    for x in tz_name.as_bytes() {
+                        f.write_all(&[convert(x)])?;
+                    }
+                }
+                Ok(())
+            }
+            Spec::WeekDayName => {
+                let index = time.day_of_week()? as usize;
+                if self.flags.has_change_or_upper_case() {
+                    self.format_string(f, DAYS_UPPER[index])
+                } else {
+                    self.format_string(f, DAYS[index])
+                }
+            }
+            Spec::WeekDayNameAbbr => {
+                let index = time.day_of_week()? as usize;
+                if self.flags.has_change_or_upper_case() {
+                    self.format_string(f, &DAYS_UPPER[index][..3])
+                } else {
+                    self.format_string(f, &DAYS[index][..3])
+                }
+            }
+            Spec::WeekDayFrom1 => {
+                let day_of_week = time.day_of_week()?;
+                let day_of_week = if day_of_week == 0 { 7 } else { day_of_week };
+                self.format_num_zeros(f, day_of_week, 1)
+            }
+            Spec::WeekDayFrom0 => self.format_num_zeros(f, time.day_of_week()?, 1),
+            Spec::YearIso8601 => {
+                let (iso_year, _) = iso_8601_year_and_week_number(
+                    time.year().into(),
+                    time.day_of_week()?.into(),
+                    time.day_of_year()?.into(),
+                );
+                let default_width = if iso_year < 0 { 5 } else { 4 };
+                self.format_num_zeros(f, iso_year, default_width)
+            }
+            Spec::YearIso8601Rem100 => {
+                let (iso_year, _) = iso_8601_year_and_week_number(
+                    time.year().into(),
+                    time.day_of_week()?.into(),
+                    time.day_of_year()?.into(),
+                );
+                self.format_num_zeros(f, iso_year.rem_euclid(100), 2)
+            }
+            Spec::WeekNumberIso8601 => {
+                let (_, iso_week_number) = iso_8601_year_and_week_number(
+                    time.year().into(),
+                    time.day_of_week()?.into(),
+                    time.day_of_year()?.into(),
+                );
+                self.format_num_zeros(f, iso_week_number, 2)
+            }
+            Spec::WeekNumberFromSunday => {
+                let week_number = week_number(
+                    time.day_of_week()?.into(),
+                    time.day_of_year()?.into(),
+                    WeekStart::Sunday,
+                );
+                self.format_num_zeros(f, week_number, 2)
+            }
+            Spec::WeekNumberFromMonday => {
+                let week_number = week_number(
+                    time.day_of_week()?.into(),
+                    time.day_of_year()?.into(),
+                    WeekStart::Monday,
+                );
+                self.format_num_zeros(f, week_number, 2)
+            }
+            Spec::SecondsSinceEpoch => self.format_num_zeros(f, time.to_int(), 1),
+            Spec::Newline => self.format_string(f, "\n"),
+            Spec::Tabulation => self.format_string(f, "\t"),
+            Spec::Percent => self.format_string(f, "%"),
+            Spec::CombinationDateTime => {
+                const MIN_WIDTH_NO_YEAR: usize = "www mmm dd HH:MM:SS ".len();
+
+                let year = time.year();
+                let default_year_width = if year < 0 { 5 } else { 4 };
+                let min_width = MIN_WIDTH_NO_YEAR + year_width(year).max(default_year_width);
+                self.write_padding(f, min_width)?;
+
+                let (day_names, month_names) = if self.flags.contains(Flag::UpperCase) {
+                    (&DAYS_UPPER, &MONTHS_UPPER)
+                } else {
+                    (&DAYS, &MONTHS)
+                };
+
+                let week_day_name = &day_names[time.day_of_week()? as usize][..3];
+                let month_name = &month_names[(time.month()? - 1) as usize][..3];
+                let day = time.day()?;
+                let (hour, minute, second) = (time.hour()?, time.minute()?, time.second()?);
+
+                write!(f, "{week_day_name} {month_name} ")?;
+                write!(f, "{day: >2} {hour:02}:{minute:02}:{second:02} ")?;
+                write!(f, "{year:0default_year_width$}")
+            }
+            Spec::CombinationDate => {
+                self.write_padding(f, "mm/dd/yy".len())?;
+
+                let year = time.year().rem_euclid(100);
+                let month = time.month()?;
+                let day = time.day()?;
+
+                write!(f, "{month:02}/{day:02}/{year:02}")
+            }
+            Spec::CombinationIso8601 => {
+                const MIN_WIDTH_NO_YEAR: usize = "-mm-dd".len();
+
+                let year = time.year();
+                let default_year_width = if year < 0 { 5 } else { 4 };
+                let min_width = MIN_WIDTH_NO_YEAR + year_width(year).max(default_year_width);
+                self.write_padding(f, min_width)?;
+
+                let month = time.month()?;
+                let day = time.day()?;
+
+                write!(f, "{year:0default_year_width$}-{month:02}-{day:02}")
+            }
+            Spec::CombinationVmsDate => {
+                let year = time.year();
+                self.write_padding(f, "dd-mmm-".len() + year_width(year).max(4))?;
+
+                let month_name = &MONTHS_UPPER[(time.month()? - 1) as usize][..3];
+                let day = time.day()?;
+
+                write!(f, "{day: >2}-{month_name}-{year:04}")
+            }
+            Spec::CombinationTime12h => {
+                self.write_padding(f, "HH:MM:SS PM".len())?;
+
+                let hour = time.hour()? % 12;
+                let hour = if hour == 0 { 12 } else { hour };
+
+                let (minute, second) = (time.minute()?, time.second()?);
+                let meridian = if time.hour()? < 12 { "AM" } else { "PM" };
+
+                write!(f, "{hour:02}:{minute:02}:{second:02} {meridian}")
+            }
+            Spec::CombinationHourMinute24h => {
+                self.write_padding(f, "HH:MM".len())?;
+                let (hour, minute) = (time.hour()?, time.minute()?);
+                write!(f, "{hour:02}:{minute:02}")
+            }
+            Spec::CombinationTime24h => {
+                self.write_padding(f, "HH:MM:SS".len())?;
+                let (hour, minute, second) = (time.hour()?, time.minute()?, time.second()?);
+                write!(f, "{hour:02}:{minute:02}:{second:02}")
+            }
+        }
+    }
+}
+
+/// Wrapper struct for formatting time with the provided format string.
+pub(crate) struct TimeFormatter<'t, 'f, T> {
+    /// Time implementation
+    time: &'t T,
+    /// Format string
+    format: &'f [u8],
+}
+
+impl<'t, 'f, T: CheckedTime> TimeFormatter<'t, 'f, T> {
+    /// Construct a new `TimeFormatter` wrapper.
+    pub(crate) fn new<F: AsRef<[u8]> + ?Sized>(time: &'t T, format: &'f F) -> Self {
+        Self {
+            time,
+            format: format.as_ref(),
+        }
+    }
+
+    /// Format time using the format string.
+    pub(crate) fn fmt(&self, buf: &mut dyn Write) -> Result<(), Error> {
+        // Do nothing if the format string is empty
+        if self.format.is_empty() {
+            return Ok(());
+        }
+
+        // Use a size limiter to limit the maximum size of the resulting
+        // formatted string
+        let size_limit = self.format.len().saturating_mul(512 * 1024);
+        let mut f = SizeLimiter::new(buf, size_limit);
+
+        let mut cursor = Cursor::new(self.format);
+
+        loop {
+            f.write_all(cursor.read_until(|&x| x == b'%'))?;
+
+            let remaining_before = cursor.remaining();
+
+            // Read the '%' character
+            if cursor.next().is_none() {
+                break;
+            }
+
+            if let Some(piece) = Self::parse_spec(&mut cursor)? {
+                piece.fmt(&mut f, self.time)?;
+            } else {
+                // No valid format specifier was found
+                let remaining_after = cursor.remaining();
+                let text = &remaining_before[..remaining_before.len() - remaining_after.len()];
+                f.write_all(text)?;
+            }
+        }
+
+        Ok(())
+    }
+
+    /// Parse a formatting directive.
+    fn parse_spec(cursor: &mut Cursor<'_>) -> Result<Option<Piece>, Error> {
+        // Parse flags
+        let mut padding = Padding::Left;
+        let mut flags = Flags::default();
+
+        loop {
+            // The left padding overrides the other padding options for most cases.
+            // It is also used for the hour sign in the `%z` specifier.
+            //
+            // Similarly, the change case flag overrides the upper case flag,
+            // except when using combination specifiers (`%c`, `%D`, `%x`, `%F`,
+            // `%v`, `%r`, `%R`, `%T`, `%X`).
+            match cursor.remaining().first() {
+                Some(&b'-') => {
+                    padding = Padding::Left;
+                    flags.set(Flag::LeftPadding);
+                }
+                Some(&b'_') => padding = Padding::Spaces,
+                Some(&b'0') => padding = Padding::Zeros,
+                Some(&b'^') => flags.set(Flag::UpperCase),
+                Some(&b'#') => flags.set(Flag::ChangeCase),
+                _ => break,
+            }
+            cursor.next();
+        }
+
+        // Parse width
+        let width_digits = str::from_utf8(cursor.read_while(u8::is_ascii_digit))
+            .expect("reading ASCII digits should yield a valid UTF-8 slice");
+
+        let width = match width_digits.parse::<usize>() {
+            Ok(width) if Int::try_from(width).is_ok() => Some(width),
+            Err(err) if *err.kind() == IntErrorKind::Empty => None,
+            _ => return Ok(None),
+        };
+
+        // Ignore POSIX locale extensions per MRI 3.1.2:
+        //
+        // <https://github.com/ruby/ruby/blob/v3_1_2/strftime.c#L713-L722>
+        if let Some(&[ext, spec]) = cursor.remaining().get(..2) {
+            const EXT_E_SPECS: &[u8] = assert_sorted(b"CXYcxy");
+            const EXT_O_SPECS: &[u8] = assert_sorted(b"HIMSUVWdeklmuwy");
+
+            match ext {
+                b'E' if EXT_E_SPECS.binary_search(&spec).is_ok() => cursor.next(),
+                b'O' if EXT_O_SPECS.binary_search(&spec).is_ok() => cursor.next(),
+                _ => None,
+            };
+        }
+
+        // Parse spec
+        let colons = cursor.read_while(|&x| x == b':');
+
+        let spec = if colons.is_empty() {
+            const POSSIBLE_SPECS: &[(u8, Spec)] = assert_sorted_elem_0(&[
+                (b'%', Spec::Percent),
+                (b'A', Spec::WeekDayName),
+                (b'B', Spec::MonthName),
+                (b'C', Spec::YearDiv100),
+                (b'D', Spec::CombinationDate),
+                (b'F', Spec::CombinationIso8601),
+                (b'G', Spec::YearIso8601),
+                (b'H', Spec::Hour24hZero),
+                (b'I', Spec::Hour12hZero),
+                (b'L', Spec::MilliSecond),
+                (b'M', Spec::Minute),
+                (b'N', Spec::FractionalSecond),
+                (b'P', Spec::MeridianLower),
+                (b'R', Spec::CombinationHourMinute24h),
+                (b'S', Spec::Second),
+                (b'T', Spec::CombinationTime24h),
+                (b'U', Spec::WeekNumberFromSunday),
+                (b'V', Spec::WeekNumberIso8601),
+                (b'W', Spec::WeekNumberFromMonday),
+                (b'X', Spec::CombinationTime24h),
+                (b'Y', Spec::Year4Digits),
+                (b'Z', Spec::TimeZoneName),
+                (b'a', Spec::WeekDayNameAbbr),
+                (b'b', Spec::MonthNameAbbr),
+                (b'c', Spec::CombinationDateTime),
+                (b'd', Spec::MonthDayZero),
+                (b'e', Spec::MonthDaySpace),
+                (b'g', Spec::YearIso8601Rem100),
+                (b'h', Spec::MonthNameAbbr),
+                (b'j', Spec::YearDay),
+                (b'k', Spec::Hour24hSpace),
+                (b'l', Spec::Hour12hSpace),
+                (b'm', Spec::Month),
+                (b'n', Spec::Newline),
+                (b'p', Spec::MeridianUpper),
+                (b'r', Spec::CombinationTime12h),
+                (b's', Spec::SecondsSinceEpoch),
+                (b't', Spec::Tabulation),
+                (b'u', Spec::WeekDayFrom1),
+                (b'v', Spec::CombinationVmsDate),
+                (b'w', Spec::WeekDayFrom0),
+                (b'x', Spec::CombinationDate),
+                (b'y', Spec::YearRem100),
+                (b'z', Spec::TimeZoneOffsetHourMinute),
+            ]);
+
+            match cursor.next() {
+                Some(x) => match POSSIBLE_SPECS.binary_search_by_key(&x, |&(c, _)| c) {
+                    Ok(index) => Some(POSSIBLE_SPECS[index].1),
+                    Err(_) => None,
+                },
+                None => return Err(Error::InvalidFormatString),
+            }
+        } else if cursor.read_optional_tag(b"z") {
+            match colons.len() {
+                1 => Some(Spec::TimeZoneOffsetHourMinuteColon),
+                2 => Some(Spec::TimeZoneOffsetHourMinuteSecondColon),
+                3 => Some(Spec::TimeZoneOffsetColonMinimal),
+                _ => None,
+            }
+        } else {
+            None
+        };
+
+        Ok(spec.map(|spec| Piece::new(width, padding, flags, spec)))
+    }
+}
+
+/// Compute the width of the string representation of a year.
+fn year_width(year: i32) -> usize {
+    const MINUS_SIGN_WIDTH: usize = 1;
+    let mut n = if year <= 0 { MINUS_SIGN_WIDTH } else { 0 };
+    let mut val = year;
+    while val != 0 {
+        val /= 10;
+        n += 1;
+    }
+    n
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_year_width() {
+        assert_eq!(year_width(-100), 4);
+        assert_eq!(year_width(-99), 3);
+        assert_eq!(year_width(-10), 3);
+        assert_eq!(year_width(-9), 2);
+        assert_eq!(year_width(-1), 2);
+        assert_eq!(year_width(0), 1);
+        assert_eq!(year_width(1), 1);
+        assert_eq!(year_width(9), 1);
+        assert_eq!(year_width(10), 2);
+        assert_eq!(year_width(99), 2);
+        assert_eq!(year_width(100), 3);
+    }
+
+    #[cfg(feature = "alloc")]
+    #[test]
+    fn test_flag_debug_is_non_empty() {
+        use alloc::format;
+
+        assert!(!format!("{:?}", Flag::LeftPadding).is_empty());
+        assert!(!format!("{:?}", Flag::ChangeCase).is_empty());
+        assert!(!format!("{:?}", Flag::UpperCase).is_empty());
+    }
+
+    #[cfg(feature = "alloc")]
+    #[test]
+    fn test_flags_debug_is_non_empty() {
+        use alloc::format;
+
+        assert!(!format!("{:?}", Flags::default()).is_empty());
+    }
+
+    #[cfg(feature = "alloc")]
+    #[test]
+    fn test_padding_debug_is_non_empty() {
+        use alloc::format;
+
+        assert!(!format!("{:?}", Padding::Left).is_empty());
+        assert!(!format!("{:?}", Padding::Spaces).is_empty());
+        assert!(!format!("{:?}", Padding::Zeros).is_empty());
+    }
+
+    #[cfg(feature = "alloc")]
+    #[test]
+    fn test_spec_debug_is_non_empty() {
+        use alloc::format;
+
+        assert!(!format!("{:?}", Spec::Year4Digits).is_empty());
+        assert!(!format!("{:?}", Spec::YearDiv100).is_empty());
+        assert!(!format!("{:?}", Spec::YearRem100).is_empty());
+        assert!(!format!("{:?}", Spec::Month).is_empty());
+        assert!(!format!("{:?}", Spec::MonthName).is_empty());
+        assert!(!format!("{:?}", Spec::MonthNameAbbr).is_empty());
+        assert!(!format!("{:?}", Spec::MonthDayZero).is_empty());
+        assert!(!format!("{:?}", Spec::MonthDaySpace).is_empty());
+        assert!(!format!("{:?}", Spec::YearDay).is_empty());
+        assert!(!format!("{:?}", Spec::Hour24hZero).is_empty());
+        assert!(!format!("{:?}", Spec::Hour24hSpace).is_empty());
+        assert!(!format!("{:?}", Spec::Hour12hZero).is_empty());
+        assert!(!format!("{:?}", Spec::Hour12hSpace).is_empty());
+        assert!(!format!("{:?}", Spec::MeridianLower).is_empty());
+        assert!(!format!("{:?}", Spec::MeridianUpper).is_empty());
+        assert!(!format!("{:?}", Spec::Minute).is_empty());
+        assert!(!format!("{:?}", Spec::Second).is_empty());
+        assert!(!format!("{:?}", Spec::MilliSecond).is_empty());
+        assert!(!format!("{:?}", Spec::FractionalSecond).is_empty());
+        assert!(!format!("{:?}", Spec::TimeZoneOffsetHourMinute).is_empty());
+        assert!(!format!("{:?}", Spec::TimeZoneOffsetHourMinuteColon).is_empty());
+        assert!(!format!("{:?}", Spec::TimeZoneOffsetHourMinuteSecondColon).is_empty());
+        assert!(!format!("{:?}", Spec::TimeZoneOffsetColonMinimal).is_empty());
+        assert!(!format!("{:?}", Spec::TimeZoneName).is_empty());
+        assert!(!format!("{:?}", Spec::WeekDayName).is_empty());
+        assert!(!format!("{:?}", Spec::WeekDayNameAbbr).is_empty());
+        assert!(!format!("{:?}", Spec::WeekDayFrom1).is_empty());
+        assert!(!format!("{:?}", Spec::WeekDayFrom0).is_empty());
+        assert!(!format!("{:?}", Spec::YearIso8601).is_empty());
+        assert!(!format!("{:?}", Spec::YearIso8601Rem100).is_empty());
+        assert!(!format!("{:?}", Spec::WeekNumberIso8601).is_empty());
+        assert!(!format!("{:?}", Spec::WeekNumberFromSunday).is_empty());
+        assert!(!format!("{:?}", Spec::WeekNumberFromMonday).is_empty());
+        assert!(!format!("{:?}", Spec::SecondsSinceEpoch).is_empty());
+        assert!(!format!("{:?}", Spec::Newline).is_empty());
+        assert!(!format!("{:?}", Spec::Tabulation).is_empty());
+        assert!(!format!("{:?}", Spec::Percent).is_empty());
+        assert!(!format!("{:?}", Spec::CombinationDateTime).is_empty());
+        assert!(!format!("{:?}", Spec::CombinationDate).is_empty());
+        assert!(!format!("{:?}", Spec::CombinationIso8601).is_empty());
+        assert!(!format!("{:?}", Spec::CombinationVmsDate).is_empty());
+        assert!(!format!("{:?}", Spec::CombinationTime12h).is_empty());
+        assert!(!format!("{:?}", Spec::CombinationHourMinute24h).is_empty());
+        assert!(!format!("{:?}", Spec::CombinationTime24h).is_empty());
+    }
+
+    #[cfg(feature = "alloc")]
+    #[test]
+    fn test_utc_offset_debug_is_non_empty() {
+        use alloc::format;
+
+        assert!(!format!("{:?}", UtcOffset::new(0.0, 0, 0)).is_empty());
+    }
+
+    #[cfg(feature = "alloc")]
+    #[test]
+    fn test_piece_debug_is_non_empty() {
+        use alloc::format;
+
+        let piece = Piece::new(
+            None,
+            Padding::Spaces,
+            Flags::default(),
+            Spec::CombinationTime24h,
+        );
+
+        assert!(!format!("{piece:?}").is_empty());
+    }
+}
+
\ No newline at end of file diff --git a/src/strftime/format/utils.rs.html b/src/strftime/format/utils.rs.html new file mode 100644 index 00000000..f2bf2cf1 --- /dev/null +++ b/src/strftime/format/utils.rs.html @@ -0,0 +1,219 @@ +utils.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+
//! Some useful types.
+
+use super::write::Write;
+use crate::Error;
+
+/// A `Cursor` contains a slice of a buffer.
+#[derive(Debug, Clone)]
+pub(crate) struct Cursor<'a> {
+    /// Slice representing the remaining data to be read.
+    remaining: &'a [u8],
+}
+
+impl<'a> Cursor<'a> {
+    /// Construct a new `Cursor` from remaining data.
+    pub(crate) fn new(remaining: &'a [u8]) -> Self {
+        Self { remaining }
+    }
+
+    /// Returns remaining data.
+    pub(crate) fn remaining(&self) -> &'a [u8] {
+        self.remaining
+    }
+
+    /// Returns the next byte.
+    pub(crate) fn next(&mut self) -> Option<u8> {
+        let (&first, tail) = self.remaining.split_first()?;
+        self.remaining = tail;
+        Some(first)
+    }
+
+    /// Read bytes if the remaining data is prefixed by the provided tag.
+    pub(crate) fn read_optional_tag(&mut self, tag: &[u8]) -> bool {
+        if self.remaining.starts_with(tag) {
+            self.read_exact(tag.len());
+            true
+        } else {
+            false
+        }
+    }
+
+    /// Read bytes as long as the provided predicate is true.
+    pub(crate) fn read_while<F: Fn(&u8) -> bool>(&mut self, f: F) -> &'a [u8] {
+        match self.remaining.iter().position(|x| !f(x)) {
+            None => self.read_exact(self.remaining.len()),
+            Some(position) => self.read_exact(position),
+        }
+    }
+
+    /// Read bytes until the provided predicate is true.
+    pub(crate) fn read_until<F: Fn(&u8) -> bool>(&mut self, f: F) -> &'a [u8] {
+        match self.remaining.iter().position(f) {
+            None => self.read_exact(self.remaining.len()),
+            Some(position) => self.read_exact(position),
+        }
+    }
+
+    /// Read exactly `count` bytes.
+    fn read_exact(&mut self, count: usize) -> &'a [u8] {
+        let (result, remaining) = self.remaining.split_at(count);
+        self.remaining = remaining;
+        result
+    }
+}
+
+/// A `SizeLimiter` limits the maximum amount a writer can write.
+pub(crate) struct SizeLimiter<'a> {
+    /// Inner writer.
+    inner: &'a mut dyn Write,
+    /// Size limit.
+    size_limit: usize,
+    /// Current write count.
+    count: usize,
+}
+
+impl<'a> SizeLimiter<'a> {
+    /// Construct a new `SizeLimiter`.
+    pub(crate) fn new(inner: &'a mut dyn Write, size_limit: usize) -> Self {
+        Self {
+            inner,
+            size_limit,
+            count: 0,
+        }
+    }
+}
+
+impl<'a> Write for SizeLimiter<'a> {
+    fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
+        if self.count + buf.len() > self.size_limit {
+            return Err(Error::FormattedStringTooLarge);
+        }
+
+        let written = self.inner.write(buf)?;
+        self.count += written;
+        Ok(written)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    #[cfg(feature = "alloc")]
+    #[test]
+    fn test_cursor_debug_is_non_empty() {
+        use alloc::format;
+
+        use super::Cursor;
+
+        assert!(!format!("{:?}", Cursor::new(&[])).is_empty());
+    }
+}
+
\ No newline at end of file diff --git a/src/strftime/format/week.rs.html b/src/strftime/format/week.rs.html new file mode 100644 index 00000000..3a27bfd3 --- /dev/null +++ b/src/strftime/format/week.rs.html @@ -0,0 +1,341 @@ +week.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+
//! Module containing week-related items.
+
+/// Start day of the week.
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub(crate) enum WeekStart {
+    /// Sunday.
+    Sunday = 0,
+    /// Monday.
+    Monday = 1,
+}
+
+/// Compute the week number, beginning at the provided start day of the week.
+///
+/// ## Inputs
+///
+/// * `week_day`: Day of the week from Sunday in `0..=6`.
+/// * `year_day_1`: Day of the year in `1..=366`.
+/// * `week_start`: Start day of the week.
+///
+pub(crate) fn week_number(week_day: i64, year_day_1: i64, week_start: WeekStart) -> i64 {
+    let year_day = year_day_1 - 1;
+    let start_of_first_week = (year_day - week_day + week_start as i64).rem_euclid(7);
+    (year_day + 7 - start_of_first_week) / 7
+}
+
+/// Compute the ISO 8601 week-based year and week number.
+///
+/// The first week of `YYYY` starts with a Monday and includes `YYYY-01-04`.
+/// The days in the year before the first week are in the last week of the
+/// previous year.
+///
+/// ## Inputs
+///
+/// * `year`: Year.
+/// * `week_day`: Day of the week from Sunday in `0..=6`.
+/// * `year_day_1`: Day of the year in `1..=366`.
+///
+pub(crate) fn iso_8601_year_and_week_number(
+    year: i64,
+    week_day: i64,
+    year_day_1: i64,
+) -> (i64, i64) {
+    let year_day = year_day_1 - 1;
+
+    let mut start_of_first_week = (year_day - week_day + 1).rem_euclid(7);
+
+    if start_of_first_week > 3 {
+        start_of_first_week -= 7;
+    }
+
+    if year_day < start_of_first_week {
+        // Use previous year
+        let previous_year = year - 1;
+
+        let previous_year_day = if is_leap_year(previous_year) {
+            366 + year_day
+        } else {
+            365 + year_day
+        };
+
+        return iso_8601_year_and_week_number(previous_year, week_day, previous_year_day + 1);
+    }
+
+    let week_number = (year_day + 7 - start_of_first_week) / 7;
+
+    if week_number >= 52 {
+        let last_year_day = if is_leap_year(year) { 365 } else { 364 };
+
+        let week_day_of_last_year_day = (week_day + last_year_day - year_day) % 7;
+
+        if (1..=3).contains(&week_day_of_last_year_day) {
+            let last_monday = last_year_day - (week_day_of_last_year_day - 1);
+            if year_day >= last_monday {
+                // Use next year
+                return (year + 1, 1);
+            }
+        }
+    }
+
+    // Use current year
+    (year, week_number)
+}
+
+/// Check if a year is a leap year.
+fn is_leap_year(year: i64) -> bool {
+    year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_week_number() {
+        assert_eq!(week_number(1, 0, WeekStart::Sunday), 0);
+        assert_eq!(week_number(2, 1, WeekStart::Sunday), 0);
+        assert_eq!(week_number(3, 2, WeekStart::Sunday), 0);
+        assert_eq!(week_number(4, 3, WeekStart::Sunday), 0);
+        assert_eq!(week_number(5, 4, WeekStart::Sunday), 0);
+        assert_eq!(week_number(6, 5, WeekStart::Sunday), 0);
+        assert_eq!(week_number(0, 6, WeekStart::Sunday), 1);
+        assert_eq!(week_number(1, 7, WeekStart::Sunday), 1);
+        assert_eq!(week_number(2, 8, WeekStart::Sunday), 1);
+
+        assert_eq!(week_number(0, 0, WeekStart::Monday), 0);
+        assert_eq!(week_number(1, 1, WeekStart::Monday), 1);
+        assert_eq!(week_number(2, 2, WeekStart::Monday), 1);
+        assert_eq!(week_number(3, 3, WeekStart::Monday), 1);
+        assert_eq!(week_number(4, 4, WeekStart::Monday), 1);
+        assert_eq!(week_number(5, 5, WeekStart::Monday), 1);
+        assert_eq!(week_number(6, 6, WeekStart::Monday), 1);
+        assert_eq!(week_number(7, 7, WeekStart::Monday), 1);
+        assert_eq!(week_number(8, 8, WeekStart::Monday), 2);
+
+        assert_eq!(week_number(0, 365, WeekStart::Sunday), 53);
+    }
+
+    #[test]
+    fn test_iso_8601_year_and_week() {
+        assert_eq!(iso_8601_year_and_week_number(2025, 0, 362), (2025, 52));
+        assert_eq!(iso_8601_year_and_week_number(2025, 1, 363), (2026, 1));
+        assert_eq!(iso_8601_year_and_week_number(2025, 2, 364), (2026, 1));
+        assert_eq!(iso_8601_year_and_week_number(2025, 3, 365), (2026, 1));
+        assert_eq!(iso_8601_year_and_week_number(2026, 4, 1), (2026, 1));
+        assert_eq!(iso_8601_year_and_week_number(2026, 5, 2), (2026, 1));
+        assert_eq!(iso_8601_year_and_week_number(2026, 6, 3), (2026, 1));
+        assert_eq!(iso_8601_year_and_week_number(2026, 0, 4), (2026, 1));
+        assert_eq!(iso_8601_year_and_week_number(2026, 1, 5), (2026, 2));
+
+        assert_eq!(iso_8601_year_and_week_number(2026, 0, 361), (2026, 52));
+        assert_eq!(iso_8601_year_and_week_number(2026, 1, 362), (2026, 53));
+        assert_eq!(iso_8601_year_and_week_number(2026, 2, 363), (2026, 53));
+        assert_eq!(iso_8601_year_and_week_number(2026, 3, 364), (2026, 53));
+        assert_eq!(iso_8601_year_and_week_number(2026, 4, 365), (2026, 53));
+        assert_eq!(iso_8601_year_and_week_number(2027, 5, 1), (2026, 53));
+        assert_eq!(iso_8601_year_and_week_number(2027, 6, 2), (2026, 53));
+        assert_eq!(iso_8601_year_and_week_number(2027, 0, 3), (2026, 53));
+        assert_eq!(iso_8601_year_and_week_number(2027, 1, 4), (2027, 1));
+
+        assert_eq!(iso_8601_year_and_week_number(2020, 0, 362), (2020, 52));
+        assert_eq!(iso_8601_year_and_week_number(2020, 1, 363), (2020, 53));
+        assert_eq!(iso_8601_year_and_week_number(2020, 2, 364), (2020, 53));
+        assert_eq!(iso_8601_year_and_week_number(2020, 3, 365), (2020, 53));
+        assert_eq!(iso_8601_year_and_week_number(2020, 4, 366), (2020, 53));
+        assert_eq!(iso_8601_year_and_week_number(2021, 5, 1), (2020, 53));
+        assert_eq!(iso_8601_year_and_week_number(2021, 6, 2), (2020, 53));
+        assert_eq!(iso_8601_year_and_week_number(2021, 0, 3), (2020, 53));
+        assert_eq!(iso_8601_year_and_week_number(2021, 1, 4), (2021, 1));
+    }
+
+    #[test]
+    fn test_is_leap_year() {
+        assert!(is_leap_year(2000));
+        assert!(!is_leap_year(2001));
+        assert!(is_leap_year(2004));
+        assert!(!is_leap_year(2100));
+        assert!(!is_leap_year(2200));
+        assert!(!is_leap_year(2300));
+        assert!(is_leap_year(2400));
+    }
+
+    #[cfg(feature = "alloc")]
+    #[test]
+    fn test_week_start_debug_is_non_empty() {
+        use alloc::format;
+
+        assert!(!format!("{:?}", WeekStart::Sunday).is_empty());
+        assert!(!format!("{:?}", WeekStart::Monday).is_empty());
+    }
+}
+
\ No newline at end of file diff --git a/src/strftime/format/write.rs.html b/src/strftime/format/write.rs.html new file mode 100644 index 00000000..4357e67b --- /dev/null +++ b/src/strftime/format/write.rs.html @@ -0,0 +1,383 @@ +write.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+
//! This module is a copy of the [`std::io::Write`] implementation, in order to
+//! use it in a no-std context.
+//!
+//! [`std::io::Write`]: <https://doc.rust-lang.org/std/io/trait.Write.html>
+
+#[cfg(feature = "alloc")]
+use alloc::vec::Vec;
+use core::fmt;
+use core::str;
+
+use crate::Error;
+
+/// An `Adapter` implements [`core::fmt::Write`] from a [`Write`] object,
+/// storing write errors instead of discarding them.
+struct Adapter<'a, T: ?Sized> {
+    /// Inner writer.
+    inner: &'a mut T,
+    /// Write result.
+    error: Result<(), Error>,
+}
+
+impl<T: Write + ?Sized> fmt::Write for Adapter<'_, T> {
+    fn write_str(&mut self, s: &str) -> fmt::Result {
+        match self.inner.write_all(s.as_bytes()) {
+            Ok(()) => Ok(()),
+            Err(e) => {
+                self.error = Err(e);
+                Err(fmt::Error)
+            }
+        }
+    }
+}
+
+/// Simplified copy of the [`std::io::Write`] trait.
+///
+/// [`std::io::Write`]: <https://doc.rust-lang.org/std/io/trait.Write.html>
+pub(crate) trait Write {
+    /// Write a buffer into this writer, returning how many bytes were written.
+    fn write(&mut self, data: &[u8]) -> Result<usize, Error>;
+
+    /// Attempts to write an entire buffer into this writer.
+    fn write_all(&mut self, mut data: &[u8]) -> Result<(), Error> {
+        while !data.is_empty() {
+            match self.write(data)? {
+                0 => return Err(Error::WriteZero),
+                n => data = &data[n..],
+            }
+        }
+        Ok(())
+    }
+
+    /// Writes a formatted string into this writer, returning any error
+    /// encountered.
+    fn write_fmt(&mut self, fmt_args: fmt::Arguments<'_>) -> Result<(), Error> {
+        let mut output = Adapter {
+            inner: self,
+            error: Ok(()),
+        };
+
+        match fmt::write(&mut output, fmt_args) {
+            Ok(()) => Ok(()),
+            Err(_) if output.error.is_err() => output.error,
+            Err(err) => Err(err.into()),
+        }
+    }
+}
+
+/// Write is implemented for `&mut [u8]` by copying into the slice, overwriting
+/// its data.
+impl Write for &mut [u8] {
+    fn write(&mut self, data: &[u8]) -> Result<usize, Error> {
+        let size = data.len().min(self.len());
+        let (a, b) = core::mem::take(self).split_at_mut(size);
+        a.copy_from_slice(&data[..size]);
+        *self = b;
+        Ok(size)
+    }
+}
+
+/// Wrapper for a [`core::fmt::Write`] writer.
+pub(crate) struct FmtWrite<'a> {
+    /// Inner writer.
+    inner: &'a mut dyn fmt::Write,
+}
+
+impl<'a> FmtWrite<'a> {
+    /// Construct a new `FmtWrite`.
+    pub(crate) fn new(inner: &'a mut dyn fmt::Write) -> Self {
+        Self { inner }
+    }
+}
+
+/// Write is implemented for `FmtWrite` by writing to its inner writer.
+impl Write for FmtWrite<'_> {
+    fn write(&mut self, data: &[u8]) -> Result<usize, Error> {
+        let data = str::from_utf8(data).expect("FmtWrite should only receive UTF-8 data");
+        self.inner.write_str(data)?;
+        Ok(data.len())
+    }
+
+    fn write_fmt(&mut self, fmt_args: fmt::Arguments<'_>) -> Result<(), Error> {
+        Ok(self.inner.write_fmt(fmt_args)?)
+    }
+}
+
+/// Write is implemented for `Vec<u8>` by appending to the vector, growing as
+/// needed.
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+impl Write for Vec<u8> {
+    fn write(&mut self, data: &[u8]) -> Result<usize, Error> {
+        self.try_reserve(data.len())?;
+        self.extend_from_slice(data);
+        Ok(data.len())
+    }
+}
+
+/// Wrapper for a [`std::io::Write`] writer.
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+pub(crate) struct IoWrite<'a> {
+    /// Inner writer.
+    inner: &'a mut dyn std::io::Write,
+}
+
+#[cfg(feature = "std")]
+impl<'a> IoWrite<'a> {
+    /// Construct a new `IoWrite`.
+    pub(crate) fn new(inner: &'a mut dyn std::io::Write) -> Self {
+        Self { inner }
+    }
+}
+
+/// Write is implemented for `IoWrite` by writing to its inner writer.
+#[cfg(feature = "std")]
+impl Write for IoWrite<'_> {
+    fn write(&mut self, data: &[u8]) -> Result<usize, Error> {
+        Ok(self.inner.write(data)?)
+    }
+
+    fn write_all(&mut self, data: &[u8]) -> Result<(), Error> {
+        Ok(self.inner.write_all(data)?)
+    }
+
+    fn write_fmt(&mut self, fmt_args: fmt::Arguments<'_>) -> Result<(), Error> {
+        Ok(self.inner.write_fmt(fmt_args)?)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_fmt_error() {
+        use core::fmt;
+
+        struct S;
+
+        impl fmt::Display for S {
+            fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
+                Err(fmt::Error)
+            }
+        }
+
+        let result = write!(&mut &mut [0u8; 1][..], "{S}");
+        assert!(matches!(result, Err(Error::FmtError(_))));
+    }
+
+    #[cfg(feature = "std")]
+    #[test]
+    fn test_io_write() {
+        let mut buf = Vec::new();
+
+        let mut writer = IoWrite::new(&mut buf);
+        writer.write_all(b"ok").unwrap();
+        write!(writer, "{}", 1).unwrap();
+
+        assert_eq!(buf, *b"ok1");
+    }
+
+    #[cfg(feature = "alloc")]
+    #[test]
+    fn test_fmt_write() {
+        use alloc::string::String;
+
+        let mut buf = String::new();
+        write!(FmtWrite::new(&mut buf), "{}", 1).unwrap();
+        assert_eq!(buf, "1");
+    }
+}
+
\ No newline at end of file diff --git a/src/strftime/lib.rs.html b/src/strftime/lib.rs.html new file mode 100644 index 00000000..364c8492 --- /dev/null +++ b/src/strftime/lib.rs.html @@ -0,0 +1,1049 @@ +lib.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+
#![forbid(unsafe_code)]
+#![warn(clippy::all)]
+#![warn(clippy::pedantic)]
+#![warn(clippy::cargo)]
+#![allow(clippy::cast_possible_truncation)]
+#![allow(unknown_lints)]
+#![warn(missing_copy_implementations)]
+#![warn(missing_debug_implementations)]
+#![warn(missing_docs)]
+#![warn(rust_2018_idioms)]
+#![warn(trivial_casts, trivial_numeric_casts)]
+#![warn(unsafe_op_in_unsafe_fn)]
+#![warn(unused_qualifications)]
+#![warn(variant_size_differences)]
+// Enable feature callouts in generated documentation:
+// https://doc.rust-lang.org/beta/unstable-book/language-features/doc-cfg.html
+//
+// This approach is borrowed from tokio.
+#![cfg_attr(docsrs, feature(doc_cfg))]
+#![cfg_attr(docsrs, feature(doc_alias))]
+
+//! This crate provides a Ruby 3.1.2 compatible `strftime` function, which
+//! formats time according to the directives in the given format string.
+//!
+//! The directives begin with a percent `%` character. Any text not listed as a
+//! directive will be passed through to the output string.
+//!
+//! Each directive consists of a percent `%` character, zero or more flags,
+//! optional minimum field width, optional modifier and a conversion specifier
+//! as follows:
+//!
+//! ```text
+//! %<flags><width><modifier><conversion>
+//! ```
+//!
+//! # Usage
+//!
+//! The various `strftime` functions in this crate take a generic _time_
+//! parameter that implements the [`Time`] trait.
+//!
+//! # Format Specifiers
+//!
+//! ## Flags
+//!
+//! | Flag | Description                                                                            |
+//! |------|----------------------------------------------------------------------------------------|
+//! |  `-` | Use left padding, ignoring width and removing all other padding options in most cases. |
+//! |  `_` | Use spaces for padding.                                                                |
+//! |  `0` | Use zeros for padding.                                                                 |
+//! |  `^` | Convert the resulting string to uppercase.                                             |
+//! |  `#` | Change case of the resulting string.                                                   |
+//!
+//!
+//! ## Width
+//!
+//! The minimum field width specifies the minimum width.
+//!
+//! ## Modifiers
+//!
+//! The modifiers are `E` and `O`. They are ignored.
+//!
+//! ## Specifiers
+//!
+//! | Specifier  | Example       | Description                                                                                                           |
+//! |------------|---------------|-----------------------------------------------------------------------------------------------------------------------|
+//! |    `%Y`    | `-2001`       | Year with century if provided, zero-padded to at least 4 digits plus the possible negative sign.                      |
+//! |    `%C`    | `-21`         | `Year / 100` using Euclidean division, zero-padded to at least 2 digits.                                              |
+//! |    `%y`    | `99`          | `Year % 100` in `00..=99`, using Euclidean remainder, zero-padded to 2 digits.                                        |
+//! |    `%m`    | `01`          | Month of the year in `01..=12`, zero-padded to 2 digits.                                                              |
+//! |    `%B`    | `July`        | Locale independent full month name.                                                                                   |
+//! | `%b`, `%h` | `Jul`         | Locale independent abbreviated month name, using the first 3 letters.                                                 |
+//! |    `%d`    | `01`          | Day of the month in `01..=31`, zero-padded to 2 digits.                                                               |
+//! |    `%e`    | ` 1`          | Day of the month in ` 1..=31`, blank-padded to 2 digits.                                                              |
+//! |    `%j`    | `001`         | Day of the year in `001..=366`, zero-padded to 3 digits.                                                              |
+//! |    `%H`    | `00`          | Hour of the day (24-hour clock) in `00..=23`, zero-padded to 2 digits.                                                |
+//! |    `%k`    | ` 0`          | Hour of the day (24-hour clock) in ` 0..=23`, blank-padded to 2 digits.                                               |
+//! |    `%I`    | `01`          | Hour of the day (12-hour clock) in `01..=12`, zero-padded to 2 digits.                                                |
+//! |    `%l`    | ` 1`          | Hour of the day (12-hour clock) in ` 1..=12`, blank-padded to 2 digits.                                               |
+//! |    `%P`    | `am`          | Lowercase meridian indicator (`"am"` or `"pm"`).                                                                      |
+//! |    `%p`    | `AM`          | Uppercase meridian indicator (`"AM"` or `"PM"`).                                                                      |
+//! |    `%M`    | `00`          | Minute of the hour in `00..=59`, zero-padded to 2 digits.                                                             |
+//! |    `%S`    | `00`          | Second of the minute in `00..=60`, zero-padded to 2 digits.                                                           |
+//! |    `%L`    | `123`         | Truncated fractional seconds digits, with 3 digits by default. Number of digits is specified by the width field.      |
+//! |    `%N`    | `123456789`   | Truncated fractional seconds digits, with 9 digits by default. Number of digits is specified by the width field.      |
+//! |    `%z`    | `+0200`       | Zero-padded signed time zone UTC hour and minute offsets (`+hhmm`).                                                   |
+//! |    `%:z`   | `+02:00`      | Zero-padded signed time zone UTC hour and minute offsets with colons (`+hh:mm`).                                      |
+//! |    `%::z`  | `+02:00:00`   | Zero-padded signed time zone UTC hour, minute and second offsets with colons (`+hh:mm:ss`).                           |
+//! |    `%:::z` | `+02`         | Zero-padded signed time zone UTC hour offset, with optional minute and second offsets with colons (`+hh[:mm[:ss]]`).  |
+//! |    `%Z`    | `CEST`        | Platform-dependent abbreviated time zone name.                                                                        |
+//! |    `%A`    | `Sunday`      | Locale independent full weekday name.                                                                                 |
+//! |    `%a`    | `Sun`         | Locale independent abbreviated weekday name, using the first 3 letters.                                               |
+//! |    `%u`    | `1`           | Day of the week from Monday in `1..=7`, zero-padded to 1 digit.                                                       |
+//! |    `%w`    | `0`           | Day of the week from Sunday in `0..=6`, zero-padded to 1 digit.                                                       |
+//! |    `%G`    | `-2001`       | Same as `%Y`, but using the ISO 8601 week-based year. [^1]                                                            |
+//! |    `%g`    | `99`          | Same as `%y`, but using the ISO 8601 week-based year. [^1]                                                            |
+//! |    `%V`    | `01`          | ISO 8601 week number in `01..=53`, zero-padded to 2 digits. [^1]                                                      |
+//! |    `%U`    | `00`          | Week number from Sunday in `00..=53`, zero-padded to 2 digits. The week `1` starts with the first Sunday of the year. |
+//! |    `%W`    | `00`          | Week number from Monday in `00..=53`, zero-padded to 2 digits. The week `1` starts with the first Monday of the year. |
+//! |    `%s`    | `86400`       | Number of seconds since `1970-01-01 00:00:00 UTC`, zero-padded to at least 1 digit.                                   |
+//! |    `%n`    | `\n`          | Newline character `'\n'`.                                                                                             |
+//! |    `%t`    | `\t`          | Tab character `'\t'`.                                                                                                 |
+//! |    `%%`    | `%`           | Literal `'%'` character.                                                                                              |
+//! |    `%c`    | `Sun Jul  8 00:23:45 2001` | Date and time, equivalent to `"%a %b %e %H:%M:%S %Y"`.                                                   |
+//! | `%D`, `%x` | `07/08/01`    | Date, equivalent to `"%m/%d/%y"`.                                                                                     |
+//! |    `%F`    | `2001-07-08`  | ISO 8601 date, equivalent to `"%Y-%m-%d"`.                                                                            |
+//! |    `%v`    | ` 8-JUL-2001` | VMS date, equivalent to `"%e-%^b-%4Y"`.                                                                               |
+//! |    `%r`    | `12:23:45 AM` | 12-hour time, equivalent to `"%I:%M:%S %p"`.                                                                          |
+//! |    `%R`    | `00:23`       | 24-hour time without seconds, equivalent to `"%H:%M"`.                                                                |
+//! | `%T`, `%X` | `00:23:45`    | 24-hour time, equivalent to `"%H:%M:%S"`.                                                                             |
+//!
+//! [^1]: `%G`, `%g`, `%V`: Week 1 of ISO 8601 is the first week with at least 4
+//! days in that year. The days before the first week are in the last week of
+//! the previous year.
+
+#![doc(html_root_url = "https://docs.rs/strftime-ruby/1.0.1")]
+#![no_std]
+
+#[cfg(feature = "alloc")]
+extern crate alloc;
+
+#[cfg(feature = "std")]
+extern crate std;
+
+#[cfg(feature = "alloc")]
+use alloc::collections::TryReserveError;
+
+mod format;
+
+#[cfg(test)]
+mod tests;
+
+/// Error type returned by the `strftime` functions.
+#[derive(Debug)]
+// To ensure the API is the same for all feature combinations, do not derive
+// `Copy`. The `OutOfMemory` variant (when it is enabled by `alloc`) contains a
+// member that is not `Copy`.
+#[non_exhaustive]
+#[allow(missing_copy_implementations)]
+#[allow(variant_size_differences)]
+pub enum Error {
+    /// Provided time implementation returns invalid values.
+    InvalidTime,
+    /// Provided format string is ended by an unterminated format specifier.
+    InvalidFormatString,
+    /// Formatted string is too large and could cause an out-of-memory error.
+    FormattedStringTooLarge,
+    /// Provided buffer for the [`buffered::strftime`] function is too small for
+    /// the formatted string.
+    ///
+    /// This corresponds to the [`std::io::ErrorKind::WriteZero`] variant.
+    ///
+    /// [`std::io::ErrorKind::WriteZero`]: <https://doc.rust-lang.org/std/io/enum.ErrorKind.html#variant.WriteZero>
+    WriteZero,
+    /// Formatting error, corresponding to [`core::fmt::Error`].
+    FmtError(core::fmt::Error),
+    /// An allocation failure has occurred in either [`bytes::strftime`] or
+    /// [`string::strftime`].
+    #[cfg(feature = "alloc")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+    OutOfMemory(TryReserveError),
+    /// An I/O error has occurred in [`io::strftime`].
+    #[cfg(feature = "std")]
+    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+    IoError(std::io::Error),
+}
+
+impl core::fmt::Display for Error {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        match self {
+            Error::InvalidTime => f.write_str("invalid time"),
+            Error::InvalidFormatString => f.write_str("invalid format string"),
+            Error::FormattedStringTooLarge => f.write_str("formatted string too large"),
+            Error::WriteZero => f.write_str("failed to write the whole buffer"),
+            Error::FmtError(_) => f.write_str("formatter error"),
+            #[cfg(feature = "alloc")]
+            Error::OutOfMemory(_) => f.write_str("allocation failure"),
+            #[cfg(feature = "std")]
+            Error::IoError(_) => f.write_str("I/O error"),
+        }
+    }
+}
+
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+impl std::error::Error for Error {
+    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+        match self {
+            Self::FmtError(inner) => Some(inner),
+            Self::OutOfMemory(inner) => Some(inner),
+            Self::IoError(inner) => Some(inner),
+            _ => None,
+        }
+    }
+}
+
+impl From<core::fmt::Error> for Error {
+    fn from(err: core::fmt::Error) -> Self {
+        Self::FmtError(err)
+    }
+}
+
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+impl From<TryReserveError> for Error {
+    fn from(err: TryReserveError) -> Self {
+        Self::OutOfMemory(err)
+    }
+}
+
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+impl From<std::io::Error> for Error {
+    fn from(err: std::io::Error) -> Self {
+        Self::IoError(err)
+    }
+}
+
+/// Common methods needed for formatting _time_.
+///
+/// This should be implemented for structs representing a _time_.
+///
+/// All the `strftime` functions take as input an implementation of this trait.
+pub trait Time {
+    /// Returns the year for _time_ (including the century).
+    fn year(&self) -> i32;
+    /// Returns the month of the year in `1..=12` for _time_.
+    fn month(&self) -> u8;
+    /// Returns the day of the month in `1..=31` for _time_.
+    fn day(&self) -> u8;
+    /// Returns the hour of the day in `0..=23` for _time_.
+    fn hour(&self) -> u8;
+    /// Returns the minute of the hour in `0..=59` for _time_.
+    fn minute(&self) -> u8;
+    /// Returns the second of the minute in `0..=60` for _time_.
+    fn second(&self) -> u8;
+    /// Returns the number of nanoseconds in `0..=999_999_999` for _time_.
+    fn nanoseconds(&self) -> u32;
+    /// Returns an integer representing the day of the week in `0..=6`, with
+    /// `Sunday == 0`.
+    fn day_of_week(&self) -> u8;
+    /// Returns an integer representing the day of the year in `1..=366`.
+    fn day_of_year(&self) -> u16;
+    /// Returns the number of seconds as a signed integer since the Epoch.
+    fn to_int(&self) -> i64;
+    /// Returns true if the time zone is UTC.
+    fn is_utc(&self) -> bool;
+    /// Returns the offset in seconds between the timezone of _time_ and UTC.
+    fn utc_offset(&self) -> i32;
+    /// Returns the name of the time zone as a string.
+    fn time_zone(&self) -> &str;
+}
+
+// Check that the Time trait is object-safe
+const _: Option<&dyn Time> = None;
+
+/// Format string used by Ruby [`Time#asctime`] method.
+///
+/// [`Time#asctime`]: <https://ruby-doc.org/core-3.1.2/Time.html#method-i-asctime>
+pub const ASCTIME_FORMAT_STRING: &str = "%c";
+
+/// Provides a `strftime` implementation using a format string with arbitrary
+/// bytes, writing to a provided byte slice.
+pub mod buffered {
+    use super::{Error, Time};
+    use crate::format::TimeFormatter;
+
+    /// Format a _time_ implementation with the specified format byte string,
+    /// writing in the provided buffer and returning the written subslice.
+    ///
+    /// See the [crate-level documentation](crate) for a complete description of
+    /// possible format specifiers.
+    ///
+    /// # Allocations
+    ///
+    /// This `strftime` implementation makes no heap allocations and is usable
+    /// in a `no_std` context.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use strftime::buffered::strftime;
+    /// use strftime::Time;
+    ///
+    /// // Not shown: create a time implementation with the year 1970
+    /// // let time = ...;
+    /// # include!("mock.rs.in");
+    /// # fn main() -> Result<(), strftime::Error> {
+    /// # let time = MockTime { year: 1970, ..Default::default() };
+    /// assert_eq!(time.year(), 1970);
+    ///
+    /// let mut buf = [0u8; 8];
+    /// assert_eq!(strftime(&time, b"%Y", &mut buf)?, b"1970");
+    /// assert_eq!(buf, *b"1970\0\0\0\0");
+    /// # Ok(())
+    /// # }
+    /// ```
+    ///
+    /// # Errors
+    ///
+    /// Can produce an [`Error`] when the formatting fails.
+    pub fn strftime<'a>(
+        time: &impl Time,
+        format: &[u8],
+        buf: &'a mut [u8],
+    ) -> Result<&'a mut [u8], Error> {
+        let len = buf.len();
+
+        let mut cursor = &mut buf[..];
+        TimeFormatter::new(time, format).fmt(&mut cursor)?;
+        let remaining_len = cursor.len();
+
+        Ok(&mut buf[..len - remaining_len])
+    }
+}
+
+/// Provides a `strftime` implementation using a UTF-8 format string, writing to
+/// a [`core::fmt::Write`] object.
+pub mod fmt {
+    use core::fmt::Write;
+
+    use super::{Error, Time};
+    use crate::format::{FmtWrite, TimeFormatter};
+
+    /// Format a _time_ implementation with the specified UTF-8 format string,
+    /// writing to the provided [`core::fmt::Write`] object.
+    ///
+    /// See the [crate-level documentation](crate) for a complete description of
+    /// possible format specifiers.
+    ///
+    /// # Allocations
+    ///
+    /// This `strftime` implementation makes no heap allocations on its own, but
+    /// the provided writer may allocate.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use strftime::fmt::strftime;
+    /// use strftime::Time;
+    ///
+    /// // Not shown: create a time implementation with the year 1970
+    /// // let time = ...;
+    /// # include!("mock.rs.in");
+    /// # fn main() -> Result<(), strftime::Error> {
+    /// # let time = MockTime { year: 1970, ..Default::default() };
+    /// assert_eq!(time.year(), 1970);
+    ///
+    /// let mut buf = String::new();
+    /// strftime(&time, "%Y", &mut buf)?;
+    /// assert_eq!(buf, "1970");
+    /// # Ok(())
+    /// # }
+    /// ```
+    ///
+    /// # Errors
+    ///
+    /// Can produce an [`Error`] when the formatting fails.
+    pub fn strftime(time: &impl Time, format: &str, buf: &mut dyn Write) -> Result<(), Error> {
+        TimeFormatter::new(time, format).fmt(&mut FmtWrite::new(buf))
+    }
+}
+
+/// Provides a `strftime` implementation using a format string with arbitrary
+/// bytes, writing to a newly allocated [`Vec`].
+///
+/// [`Vec`]: alloc::vec::Vec
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+pub mod bytes {
+    use alloc::vec::Vec;
+
+    use super::{Error, Time};
+    use crate::format::TimeFormatter;
+
+    /// Format a _time_ implementation with the specified format byte string.
+    ///
+    /// See the [crate-level documentation](crate) for a complete description of
+    /// possible format specifiers.
+    ///
+    /// # Allocations
+    ///
+    /// This `strftime` implementation writes its output to a heap-allocated
+    /// [`Vec`]. The implementation exclusively uses fallible allocation APIs
+    /// like [`Vec::try_reserve`]. This function will return [`Error::OutOfMemory`]
+    /// if there is an allocation failure.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use strftime::bytes::strftime;
+    /// use strftime::Time;
+    ///
+    /// // Not shown: create a time implementation with the year 1970
+    /// // let time = ...;
+    /// # include!("mock.rs.in");
+    /// # fn main() -> Result<(), strftime::Error> {
+    /// # let time = MockTime { year: 1970, ..Default::default() };
+    /// assert_eq!(time.year(), 1970);
+    ///
+    /// assert_eq!(strftime(&time, b"%Y")?, b"1970");
+    /// # Ok(())
+    /// # }
+    /// ```
+    ///
+    /// # Errors
+    ///
+    /// Can produce an [`Error`] when the formatting fails.
+    pub fn strftime(time: &impl Time, format: &[u8]) -> Result<Vec<u8>, Error> {
+        let mut buf = Vec::new();
+        TimeFormatter::new(time, format).fmt(&mut buf)?;
+        Ok(buf)
+    }
+}
+
+/// Provides a `strftime` implementation using a UTF-8 format string, writing to
+/// a newly allocated [`String`].
+///
+/// [`String`]: alloc::string::String
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+pub mod string {
+    use alloc::string::String;
+    use alloc::vec::Vec;
+
+    use super::{Error, Time};
+    use crate::format::TimeFormatter;
+
+    /// Format a _time_ implementation with the specified UTF-8 format string.
+    ///
+    /// See the [crate-level documentation](crate) for a complete description of
+    /// possible format specifiers.
+    ///
+    /// # Allocations
+    ///
+    /// This `strftime` implementation writes its output to a heap-allocated
+    /// [`Vec`]. The implementation exclusively uses fallible allocation APIs
+    /// like [`Vec::try_reserve`]. This function will return [`Error::OutOfMemory`]
+    /// if there is an allocation failure.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use strftime::string::strftime;
+    /// use strftime::Time;
+    ///
+    /// // Not shown: create a time implementation with the year 1970
+    /// // let time = ...;
+    /// # include!("mock.rs.in");
+    /// # fn main() -> Result<(), strftime::Error> {
+    /// # let time = MockTime { year: 1970, ..Default::default() };
+    /// assert_eq!(time.year(), 1970);
+    ///
+    /// assert_eq!(strftime(&time, "%Y")?, "1970");
+    /// # Ok(())
+    /// # }
+    /// ```
+    ///
+    /// # Errors
+    ///
+    /// Can produce an [`Error`] when the formatting fails.
+    #[allow(clippy::missing_panics_doc)]
+    pub fn strftime(time: &impl Time, format: &str) -> Result<String, Error> {
+        let mut buf = Vec::new();
+        TimeFormatter::new(time, format).fmt(&mut buf)?;
+        Ok(String::from_utf8(buf).expect("formatted string should be valid UTF-8"))
+    }
+}
+
+/// Provides a `strftime` implementation using a format string with arbitrary
+/// bytes, writing to a [`std::io::Write`] object.
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+pub mod io {
+    use std::io::Write;
+
+    use super::{Error, Time};
+    use crate::format::{IoWrite, TimeFormatter};
+
+    /// Format a _time_ implementation with the specified format byte string,
+    /// writing to the provided [`std::io::Write`] object.
+    ///
+    /// See the [crate-level documentation](crate) for a complete description of
+    /// possible format specifiers.
+    ///
+    /// # Allocations
+    ///
+    /// This `strftime` implementation makes no heap allocations on its own, but
+    /// the provided writer may allocate.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use strftime::io::strftime;
+    /// use strftime::Time;
+    ///
+    /// // Not shown: create a time implementation with the year 1970
+    /// // let time = ...;
+    /// # include!("mock.rs.in");
+    /// # fn main() -> Result<(), strftime::Error> {
+    /// # let time = MockTime { year: 1970, ..Default::default() };
+    /// assert_eq!(time.year(), 1970);
+    ///
+    /// let mut buf = Vec::new();
+    /// strftime(&time, b"%Y", &mut buf)?;
+    /// assert_eq!(buf, *b"1970");
+    /// # Ok(())
+    /// # }
+    /// ```
+    ///
+    /// # Errors
+    ///
+    /// Can produce an [`Error`] when the formatting fails.
+    pub fn strftime(time: &impl Time, format: &[u8], buf: &mut dyn Write) -> Result<(), Error> {
+        TimeFormatter::new(time, format).fmt(&mut IoWrite::new(buf))
+    }
+}
+
+// Ensure code blocks in `README.md` compile.
+//
+// This module declaration should be kept at the end of the file, in order to
+// not interfere with code coverage.
+#[cfg(all(doctest, feature = "std"))]
+#[doc = include_str!("../README.md")]
+mod readme {}
+
\ No newline at end of file diff --git a/static.files/COPYRIGHT-23e9bde6c69aea69.txt b/static.files/COPYRIGHT-23e9bde6c69aea69.txt new file mode 100644 index 00000000..1447df79 --- /dev/null +++ b/static.files/COPYRIGHT-23e9bde6c69aea69.txt @@ -0,0 +1,50 @@ +# REUSE-IgnoreStart + +These documentation pages include resources by third parties. This copyright +file applies only to those resources. The following third party resources are +included, and carry their own copyright notices and license terms: + +* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2): + + Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ + with Reserved Font Name Fira Sans. + + Copyright (c) 2014, Telefonica S.A. + + Licensed under the SIL Open Font License, Version 1.1. + See FiraSans-LICENSE.txt. + +* rustdoc.css, main.js, and playpen.js: + + Copyright 2015 The Rust Developers. + Licensed under the Apache License, Version 2.0 (see LICENSE-APACHE.txt) or + the MIT license (LICENSE-MIT.txt) at your option. + +* normalize.css: + + Copyright (c) Nicolas Gallagher and Jonathan Neal. + Licensed under the MIT license (see LICENSE-MIT.txt). + +* Source Code Pro (SourceCodePro-Regular.ttf.woff2, + SourceCodePro-Semibold.ttf.woff2, SourceCodePro-It.ttf.woff2): + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), + with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark + of Adobe Systems Incorporated in the United States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceCodePro-LICENSE.txt. + +* Source Serif 4 (SourceSerif4-Regular.ttf.woff2, SourceSerif4-Bold.ttf.woff2, + SourceSerif4-It.ttf.woff2): + + Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name + 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United + States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceSerif4-LICENSE.md. + +This copyright file is intended to be distributed with rustdoc output. + +# REUSE-IgnoreEnd diff --git a/static.files/FiraSans-LICENSE-db4b642586e02d97.txt b/static.files/FiraSans-LICENSE-db4b642586e02d97.txt new file mode 100644 index 00000000..d7e9c149 --- /dev/null +++ b/static.files/FiraSans-LICENSE-db4b642586e02d97.txt @@ -0,0 +1,98 @@ +// REUSE-IgnoreStart + +Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. +with Reserved Font Name < Fira >, + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 b/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 new file mode 100644 index 00000000..7a1e5fc5 Binary files /dev/null and b/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 differ diff --git a/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 b/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 new file mode 100644 index 00000000..e766e06c Binary files /dev/null and b/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 differ diff --git a/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt b/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt new file mode 100644 index 00000000..16fe87b0 --- /dev/null +++ b/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/static.files/LICENSE-MIT-65090b722b3f6c56.txt b/static.files/LICENSE-MIT-65090b722b3f6c56.txt new file mode 100644 index 00000000..31aa7938 --- /dev/null +++ b/static.files/LICENSE-MIT-65090b722b3f6c56.txt @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 b/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 new file mode 100644 index 00000000..1866ad4b Binary files /dev/null and b/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 differ diff --git a/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt b/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt new file mode 100644 index 00000000..4b3edc29 --- /dev/null +++ b/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt @@ -0,0 +1,103 @@ +// REUSE-IgnoreStart + +Copyright (c) 2010, NAVER Corporation (https://www.navercorp.com/), + +with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic, +NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen, +Naver NanumPen, Naver NanumGothicEco, NanumGothicEco, Naver NanumMyeongjoEco, +NanumMyeongjoEco, Naver NanumGothicLight, NanumGothicLight, NanumBarunGothic, +Naver NanumBarunGothic, NanumSquareRound, NanumBarunPen, MaruBuri + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 b/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 new file mode 100644 index 00000000..462c34ef Binary files /dev/null and b/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 differ diff --git a/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt b/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt new file mode 100644 index 00000000..0d2941e1 --- /dev/null +++ b/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt @@ -0,0 +1,97 @@ +// REUSE-IgnoreStart + +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 b/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 new file mode 100644 index 00000000..10b558e0 Binary files /dev/null and b/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 differ diff --git a/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 b/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 new file mode 100644 index 00000000..5ec64eef Binary files /dev/null and b/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 differ diff --git a/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 b/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 new file mode 100644 index 00000000..181a07f6 Binary files /dev/null and b/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 differ diff --git a/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 b/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 new file mode 100644 index 00000000..2ae08a7b Binary files /dev/null and b/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 differ diff --git a/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md b/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md new file mode 100644 index 00000000..175fa4f4 --- /dev/null +++ b/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md @@ -0,0 +1,98 @@ + + +Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. +Copyright 2014 - 2023 Adobe (http://www.adobe.com/), with Reserved Font Name ‘Source’. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + + diff --git a/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 b/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 new file mode 100644 index 00000000..0263fc30 Binary files /dev/null and b/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 differ diff --git a/static.files/clipboard-7571035ce49a181d.svg b/static.files/clipboard-7571035ce49a181d.svg new file mode 100644 index 00000000..8adbd996 --- /dev/null +++ b/static.files/clipboard-7571035ce49a181d.svg @@ -0,0 +1 @@ + diff --git a/static.files/favicon-16x16-8b506e7a72182f1c.png b/static.files/favicon-16x16-8b506e7a72182f1c.png new file mode 100644 index 00000000..ea4b45ca Binary files /dev/null and b/static.files/favicon-16x16-8b506e7a72182f1c.png differ diff --git a/static.files/favicon-2c020d218678b618.svg b/static.files/favicon-2c020d218678b618.svg new file mode 100644 index 00000000..8b34b511 --- /dev/null +++ b/static.files/favicon-2c020d218678b618.svg @@ -0,0 +1,24 @@ + + + + + diff --git a/static.files/favicon-32x32-422f7d1d52889060.png b/static.files/favicon-32x32-422f7d1d52889060.png new file mode 100644 index 00000000..69b8613c Binary files /dev/null and b/static.files/favicon-32x32-422f7d1d52889060.png differ diff --git a/static.files/main-9dd44ab47b99a0fb.js b/static.files/main-9dd44ab47b99a0fb.js new file mode 100644 index 00000000..cfb9a38f --- /dev/null +++ b/static.files/main-9dd44ab47b99a0fb.js @@ -0,0 +1,12 @@ +"use strict";window.RUSTDOC_TOOLTIP_HOVER_MS=300;window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS=450;function resourcePath(basename,extension){return getVar("root-path")+basename+getVar("resource-suffix")+extension}function hideMain(){addClass(document.getElementById(MAIN_ID),"hidden")}function showMain(){removeClass(document.getElementById(MAIN_ID),"hidden")}function elemIsInParent(elem,parent){while(elem&&elem!==document.body){if(elem===parent){return true}elem=elem.parentElement}return false}function blurHandler(event,parentElem,hideCallback){if(!elemIsInParent(document.activeElement,parentElem)&&!elemIsInParent(event.relatedTarget,parentElem)){hideCallback()}}window.rootPath=getVar("root-path");window.currentCrate=getVar("current-crate");function setMobileTopbar(){const mobileTopbar=document.querySelector(".mobile-topbar");const locationTitle=document.querySelector(".sidebar h2.location");if(mobileTopbar){const mobileTitle=document.createElement("h2");mobileTitle.className="location";if(hasClass(document.body,"crate")){mobileTitle.innerText=`Crate ${window.currentCrate}`}else if(locationTitle){mobileTitle.innerHTML=locationTitle.innerHTML}mobileTopbar.appendChild(mobileTitle)}}function getVirtualKey(ev){if("key"in ev&&typeof ev.key!=="undefined"){return ev.key}const c=ev.charCode||ev.keyCode;if(c===27){return"Escape"}return String.fromCharCode(c)}const MAIN_ID="main-content";const SETTINGS_BUTTON_ID="settings-menu";const ALTERNATIVE_DISPLAY_ID="alternative-display";const NOT_DISPLAYED_ID="not-displayed";const HELP_BUTTON_ID="help-button";function getSettingsButton(){return document.getElementById(SETTINGS_BUTTON_ID)}function getHelpButton(){return document.getElementById(HELP_BUTTON_ID)}function getNakedUrl(){return window.location.href.split("?")[0].split("#")[0]}function insertAfter(newNode,referenceNode){referenceNode.parentNode.insertBefore(newNode,referenceNode.nextSibling)}function getOrCreateSection(id,classes){let el=document.getElementById(id);if(!el){el=document.createElement("section");el.id=id;el.className=classes;insertAfter(el,document.getElementById(MAIN_ID))}return el}function getAlternativeDisplayElem(){return getOrCreateSection(ALTERNATIVE_DISPLAY_ID,"content hidden")}function getNotDisplayedElem(){return getOrCreateSection(NOT_DISPLAYED_ID,"hidden")}function switchDisplayedElement(elemToDisplay){const el=getAlternativeDisplayElem();if(el.children.length>0){getNotDisplayedElem().appendChild(el.firstElementChild)}if(elemToDisplay===null){addClass(el,"hidden");showMain();return}el.appendChild(elemToDisplay);hideMain();removeClass(el,"hidden")}function browserSupportsHistoryApi(){return window.history&&typeof window.history.pushState==="function"}function preLoadCss(cssUrl){const link=document.createElement("link");link.href=cssUrl;link.rel="preload";link.as="style";document.getElementsByTagName("head")[0].appendChild(link)}(function(){const isHelpPage=window.location.pathname.endsWith("/help.html");function loadScript(url){const script=document.createElement("script");script.src=url;document.head.append(script)}getSettingsButton().onclick=event=>{if(event.ctrlKey||event.altKey||event.metaKey){return}window.hideAllModals(false);addClass(getSettingsButton(),"rotate");event.preventDefault();loadScript(getVar("static-root-path")+getVar("settings-js"));setTimeout(()=>{const themes=getVar("themes").split(",");for(const theme of themes){if(theme!==""){preLoadCss(getVar("root-path")+theme+".css")}}},0)};window.searchState={loadingText:"Loading search results...",input:document.getElementsByClassName("search-input")[0],outputElement:()=>{let el=document.getElementById("search");if(!el){el=document.createElement("section");el.id="search";getNotDisplayedElem().appendChild(el)}return el},title:document.title,titleBeforeSearch:document.title,timeout:null,currentTab:0,focusedByTab:[null,null,null],clearInputTimeout:()=>{if(searchState.timeout!==null){clearTimeout(searchState.timeout);searchState.timeout=null}},isDisplayed:()=>searchState.outputElement().parentElement.id===ALTERNATIVE_DISPLAY_ID,focus:()=>{searchState.input.focus()},defocus:()=>{searchState.input.blur()},showResults:search=>{if(search===null||typeof search==="undefined"){search=searchState.outputElement()}switchDisplayedElement(search);searchState.mouseMovedAfterSearch=false;document.title=searchState.title},removeQueryParameters:()=>{document.title=searchState.titleBeforeSearch;if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.hash)}},hideResults:()=>{switchDisplayedElement(null);searchState.removeQueryParameters()},getQueryStringParams:()=>{const params={};window.location.search.substring(1).split("&").map(s=>{const pair=s.split("=");params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1])});return params},setup:()=>{const search_input=searchState.input;if(!searchState.input){return}let searchLoaded=false;function loadSearch(){if(!searchLoaded){searchLoaded=true;loadScript(getVar("static-root-path")+getVar("search-js"));loadScript(resourcePath("search-index",".js"))}}search_input.addEventListener("focus",()=>{search_input.origPlaceholder=search_input.placeholder;search_input.placeholder="Type your search here.";loadSearch()});if(search_input.value!==""){loadSearch()}const params=searchState.getQueryStringParams();if(params.search!==undefined){searchState.setLoadingSearch();loadSearch()}},setLoadingSearch:()=>{const search=searchState.outputElement();search.innerHTML="

"+searchState.loadingText+"

";searchState.showResults(search)},};const toggleAllDocsId="toggle-all-docs";let savedHash="";function handleHashes(ev){if(ev!==null&&searchState.isDisplayed()&&ev.newURL){switchDisplayedElement(null);const hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.search+"#"+hash)}const elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}const pageId=window.location.hash.replace(/^#/,"");if(savedHash!==pageId){savedHash=pageId;if(pageId!==""){expandSection(pageId)}}if(savedHash.startsWith("impl-")){const splitAt=savedHash.indexOf("/");if(splitAt!==-1){const implId=savedHash.slice(0,splitAt);const assocId=savedHash.slice(splitAt+1);const implElem=document.getElementById(implId);if(implElem&&implElem.parentElement.tagName==="SUMMARY"&&implElem.parentElement.parentElement.tagName==="DETAILS"){onEachLazy(implElem.parentElement.parentElement.querySelectorAll(`[id^="${assocId}"]`),item=>{const numbered=/([^-]+)-([0-9]+)/.exec(item.id);if(item.id===assocId||(numbered&&numbered[1]===assocId)){openParentDetails(item);item.scrollIntoView();setTimeout(()=>{window.location.replace("#"+item.id)},0)}})}}}}function onHashChange(ev){hideSidebar();handleHashes(ev)}function openParentDetails(elem){while(elem){if(elem.tagName==="DETAILS"){elem.open=true}elem=elem.parentNode}}function expandSection(id){openParentDetails(document.getElementById(id))}function handleEscape(ev){searchState.clearInputTimeout();searchState.hideResults();ev.preventDefault();searchState.defocus();window.hideAllModals(true)}function handleShortcut(ev){const disableShortcuts=getSettingValue("disable-shortcuts")==="true";if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts){return}if(document.activeElement.tagName==="INPUT"&&document.activeElement.type!=="checkbox"&&document.activeElement.type!=="radio"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":ev.preventDefault();searchState.focus();break;case"+":ev.preventDefault();expandAllDocs();break;case"-":ev.preventDefault();collapseAllDocs();break;case"?":showHelp();break;default:break}}}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);function addSidebarItems(){if(!window.SIDEBAR_ITEMS){return}const sidebar=document.getElementsByClassName("sidebar-elems")[0];function block(shortty,id,longty){const filtered=window.SIDEBAR_ITEMS[shortty];if(!filtered){return}const modpath=hasClass(document.body,"mod")?"../":"";const h3=document.createElement("h3");h3.innerHTML=`${longty}`;const ul=document.createElement("ul");ul.className="block "+shortty;for(const name of filtered){let path;if(shortty==="mod"){path=`${modpath}${name}/index.html`}else{path=`${modpath}${shortty}.${name}.html`}let current_page=document.location.href.toString();if(current_page.endsWith("/")){current_page+="index.html"}const link=document.createElement("a");link.href=path;if(link.href===current_page){link.className="current"}link.textContent=name;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebar.appendChild(h3);sidebar.appendChild(ul)}if(sidebar){block("primitive","primitives","Primitive Types");block("mod","modules","Modules");block("macro","macros","Macros");block("struct","structs","Structs");block("enum","enums","Enums");block("constant","constants","Constants");block("static","static","Statics");block("trait","traits","Traits");block("fn","functions","Functions");block("type","types","Type Aliases");block("union","unions","Unions");block("foreigntype","foreign-types","Foreign Types");block("keyword","keywords","Keywords");block("opaque","opaque-types","Opaque Types");block("attr","attributes","Attribute Macros");block("derive","derives","Derive Macros");block("traitalias","trait-aliases","Trait Aliases")}}window.register_implementors=imp=>{const implementors=document.getElementById("implementors-list");const synthetic_implementors=document.getElementById("synthetic-implementors-list");const inlined_types=new Set();const TEXT_IDX=0;const SYNTHETIC_IDX=1;const TYPES_IDX=2;if(synthetic_implementors){onEachLazy(synthetic_implementors.getElementsByClassName("impl"),el=>{const aliases=el.getAttribute("data-aliases");if(!aliases){return}aliases.split(",").forEach(alias=>{inlined_types.add(alias)})})}let currentNbImpls=implementors.getElementsByClassName("impl").length;const traitName=document.querySelector(".main-heading h1 > .trait").textContent;const baseIdName="impl-"+traitName+"-";const libs=Object.getOwnPropertyNames(imp);const script=document.querySelector("script[data-ignore-extern-crates]");const ignoreExternCrates=new Set((script?script.getAttribute("data-ignore-extern-crates"):"").split(","));for(const lib of libs){if(lib===window.currentCrate||ignoreExternCrates.has(lib)){continue}const structs=imp[lib];struct_loop:for(const struct of structs){const list=struct[SYNTHETIC_IDX]?synthetic_implementors:implementors;if(struct[SYNTHETIC_IDX]){for(const struct_type of struct[TYPES_IDX]){if(inlined_types.has(struct_type)){continue struct_loop}inlined_types.add(struct_type)}}const code=document.createElement("h3");code.innerHTML=struct[TEXT_IDX];addClass(code,"code-header");onEachLazy(code.getElementsByTagName("a"),elem=>{const href=elem.getAttribute("href");if(href&&!href.startsWith("#")&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});const currentId=baseIdName+currentNbImpls;const anchor=document.createElement("a");anchor.href="#"+currentId;addClass(anchor,"anchor");const display=document.createElement("div");display.id=currentId;addClass(display,"impl");display.appendChild(anchor);display.appendChild(code);list.appendChild(display);currentNbImpls+=1}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors)}window.register_type_impls=imp=>{if(!imp||!imp[window.currentCrate]){return}window.pending_type_impls=null;const idMap=new Map();let implementations=document.getElementById("implementations-list");let trait_implementations=document.getElementById("trait-implementations-list");let trait_implementations_header=document.getElementById("trait-implementations");const script=document.querySelector("script[data-self-path]");const selfPath=script?script.getAttribute("data-self-path"):null;const mainContent=document.querySelector("#main-content");const sidebarSection=document.querySelector(".sidebar section");let methods=document.querySelector(".sidebar .block.method");let associatedTypes=document.querySelector(".sidebar .block.associatedtype");let associatedConstants=document.querySelector(".sidebar .block.associatedconstant");let sidebarTraitList=document.querySelector(".sidebar .block.trait-implementation");for(const impList of imp[window.currentCrate]){const types=impList.slice(2);const text=impList[0];const isTrait=impList[1]!==0;const traitName=impList[1];if(types.indexOf(selfPath)===-1){continue}let outputList=isTrait?trait_implementations:implementations;if(outputList===null){const outputListName=isTrait?"Trait Implementations":"Implementations";const outputListId=isTrait?"trait-implementations-list":"implementations-list";const outputListHeaderId=isTrait?"trait-implementations":"implementations";const outputListHeader=document.createElement("h2");outputListHeader.id=outputListHeaderId;outputListHeader.innerText=outputListName;outputList=document.createElement("div");outputList.id=outputListId;if(isTrait){const link=document.createElement("a");link.href=`#${outputListHeaderId}`;link.innerText="Trait Implementations";const h=document.createElement("h3");h.appendChild(link);trait_implementations=outputList;trait_implementations_header=outputListHeader;sidebarSection.appendChild(h);sidebarTraitList=document.createElement("ul");sidebarTraitList.className="block trait-implementation";sidebarSection.appendChild(sidebarTraitList);mainContent.appendChild(outputListHeader);mainContent.appendChild(outputList)}else{implementations=outputList;if(trait_implementations){mainContent.insertBefore(outputListHeader,trait_implementations_header);mainContent.insertBefore(outputList,trait_implementations_header)}else{const mainContent=document.querySelector("#main-content");mainContent.appendChild(outputListHeader);mainContent.appendChild(outputList)}}}const template=document.createElement("template");template.innerHTML=text;onEachLazy(template.content.querySelectorAll("a"),elem=>{const href=elem.getAttribute("href");if(href&&!href.startsWith("#")&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});onEachLazy(template.content.querySelectorAll("[id]"),el=>{let i=0;if(idMap.has(el.id)){i=idMap.get(el.id)}else if(document.getElementById(el.id)){i=1;while(document.getElementById(`${el.id}-${2 * i}`)){i=2*i}while(document.getElementById(`${el.id}-${i}`)){i+=1}}if(i!==0){const oldHref=`#${el.id}`;const newHref=`#${el.id}-${i}`;el.id=`${el.id}-${i}`;onEachLazy(template.content.querySelectorAll("a[href]"),link=>{if(link.getAttribute("href")===oldHref){link.href=newHref}})}idMap.set(el.id,i+1)});const templateAssocItems=template.content.querySelectorAll("section.tymethod, "+"section.method, section.associatedtype, section.associatedconstant");if(isTrait){const li=document.createElement("li");const a=document.createElement("a");a.href=`#${template.content.querySelector(".impl").id}`;a.textContent=traitName;li.appendChild(a);sidebarTraitList.append(li)}else{onEachLazy(templateAssocItems,item=>{let block=hasClass(item,"associatedtype")?associatedTypes:(hasClass(item,"associatedconstant")?associatedConstants:(methods));if(!block){const blockTitle=hasClass(item,"associatedtype")?"Associated Types":(hasClass(item,"associatedconstant")?"Associated Constants":("Methods"));const blockClass=hasClass(item,"associatedtype")?"associatedtype":(hasClass(item,"associatedconstant")?"associatedconstant":("method"));const blockHeader=document.createElement("h3");const blockLink=document.createElement("a");blockLink.href="#implementations";blockLink.innerText=blockTitle;blockHeader.appendChild(blockLink);block=document.createElement("ul");block.className=`block ${blockClass}`;const insertionReference=methods||sidebarTraitList;if(insertionReference){const insertionReferenceH=insertionReference.previousElementSibling;sidebarSection.insertBefore(blockHeader,insertionReferenceH);sidebarSection.insertBefore(block,insertionReferenceH)}else{sidebarSection.appendChild(blockHeader);sidebarSection.appendChild(block)}if(hasClass(item,"associatedtype")){associatedTypes=block}else if(hasClass(item,"associatedconstant")){associatedConstants=block}else{methods=block}}const li=document.createElement("li");const a=document.createElement("a");a.innerText=item.id.split("-")[0].split(".")[1];a.href=`#${item.id}`;li.appendChild(a);block.appendChild(li)})}outputList.appendChild(template.content)}for(const list of[methods,associatedTypes,associatedConstants,sidebarTraitList]){if(!list){continue}const newChildren=Array.prototype.slice.call(list.children);newChildren.sort((a,b)=>{const aI=a.innerText;const bI=b.innerText;return aIbI?1:0});list.replaceChildren(...newChildren)}};if(window.pending_type_impls){window.register_type_impls(window.pending_type_impls)}function addSidebarCrates(){if(!window.ALL_CRATES){return}const sidebarElems=document.getElementsByClassName("sidebar-elems")[0];if(!sidebarElems){return}const h3=document.createElement("h3");h3.innerHTML="Crates";const ul=document.createElement("ul");ul.className="block crate";for(const crate of window.ALL_CRATES){const link=document.createElement("a");link.href=window.rootPath+crate+"/index.html";if(window.rootPath!=="./"&&crate===window.currentCrate){link.className="current"}link.textContent=crate;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebarElems.appendChild(h3);sidebarElems.appendChild(ul)}function expandAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);removeClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hasClass(e,"type-contents-toggle")&&!hasClass(e,"more-examples-toggle")){e.open=true}});innerToggle.title="collapse all docs";innerToggle.children[0].innerText="\u2212"}function collapseAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);addClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(e.parentNode.id!=="implementations-list"||(!hasClass(e,"implementors-toggle")&&!hasClass(e,"type-contents-toggle"))){e.open=false}});innerToggle.title="expand all docs";innerToggle.children[0].innerText="+"}function toggleAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);if(!innerToggle){return}if(hasClass(innerToggle,"will-expand")){expandAllDocs()}else{collapseAllDocs()}}(function(){const toggles=document.getElementById(toggleAllDocsId);if(toggles){toggles.onclick=toggleAllDocs}const hideMethodDocs=getSettingValue("auto-hide-method-docs")==="true";const hideImplementations=getSettingValue("auto-hide-trait-implementations")==="true";const hideLargeItemContents=getSettingValue("auto-hide-large-items")!=="false";function setImplementorsTogglesOpen(id,open){const list=document.getElementById(id);if(list!==null){onEachLazy(list.getElementsByClassName("implementors-toggle"),e=>{e.open=open})}}if(hideImplementations){setImplementorsTogglesOpen("trait-implementations-list",false);setImplementorsTogglesOpen("blanket-implementations-list",false)}onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hideLargeItemContents&&hasClass(e,"type-contents-toggle")){e.open=true}if(hideMethodDocs&&hasClass(e,"method-toggle")){e.open=false}})}());window.rustdoc_add_line_numbers_to_examples=()=>{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");if(line_numbers.length>0){return}const count=x.textContent.split("\n").length;const elems=[];for(let i=0;i{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");for(const node of line_numbers){parent.removeChild(node)}})};if(getSettingValue("line-numbers")==="true"){window.rustdoc_add_line_numbers_to_examples()}function showSidebar(){window.hideAllModals(false);const sidebar=document.getElementsByClassName("sidebar")[0];addClass(sidebar,"shown")}function hideSidebar(){const sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"shown")}window.addEventListener("resize",()=>{if(window.CURRENT_TOOLTIP_ELEMENT){const base=window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE;const force_visible=base.TOOLTIP_FORCE_VISIBLE;hideTooltip(false);if(force_visible){showTooltip(base);base.TOOLTIP_FORCE_VISIBLE=true}}});const mainElem=document.getElementById(MAIN_ID);if(mainElem){mainElem.addEventListener("click",hideSidebar)}onEachLazy(document.querySelectorAll("a[href^='#']"),el=>{el.addEventListener("click",()=>{expandSection(el.hash.slice(1));hideSidebar()})});onEachLazy(document.querySelectorAll(".toggle > summary:not(.hideme)"),el=>{el.addEventListener("click",e=>{if(e.target.tagName!=="SUMMARY"&&e.target.tagName!=="A"){e.preventDefault()}})});function showTooltip(e){const notable_ty=e.getAttribute("data-notable-ty");if(!window.NOTABLE_TRAITS&¬able_ty){const data=document.getElementById("notable-traits-data");if(data){window.NOTABLE_TRAITS=JSON.parse(data.innerText)}else{throw new Error("showTooltip() called with notable without any notable traits!")}}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE===e){clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);return}window.hideAllModals(false);const wrapper=document.createElement("div");if(notable_ty){wrapper.innerHTML="
"+window.NOTABLE_TRAITS[notable_ty]+"
"}else{if(e.getAttribute("title")!==null){e.setAttribute("data-title",e.getAttribute("title"));e.removeAttribute("title")}if(e.getAttribute("data-title")!==null){const titleContent=document.createElement("div");titleContent.className="content";titleContent.appendChild(document.createTextNode(e.getAttribute("data-title")));wrapper.appendChild(titleContent)}}wrapper.className="tooltip popover";const focusCatcher=document.createElement("div");focusCatcher.setAttribute("tabindex","0");focusCatcher.onfocus=hideTooltip;wrapper.appendChild(focusCatcher);const pos=e.getBoundingClientRect();wrapper.style.top=(pos.top+window.scrollY+pos.height)+"px";wrapper.style.left=0;wrapper.style.right="auto";wrapper.style.visibility="hidden";const body=document.getElementsByTagName("body")[0];body.appendChild(wrapper);const wrapperPos=wrapper.getBoundingClientRect();const finalPos=pos.left+window.scrollX-wrapperPos.width+24;if(finalPos>0){wrapper.style.left=finalPos+"px"}else{wrapper.style.setProperty("--popover-arrow-offset",(wrapperPos.right-pos.right+4)+"px")}wrapper.style.visibility="";window.CURRENT_TOOLTIP_ELEMENT=wrapper;window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE=e;clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);wrapper.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}clearTooltipHoverTimeout(e)};wrapper.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&!elemIsInParent(ev.relatedTarget,e)){setTooltipHoverTimeout(e,false);addClass(wrapper,"fade-out")}}}function setTooltipHoverTimeout(element,show){clearTooltipHoverTimeout(element);if(!show&&!window.CURRENT_TOOLTIP_ELEMENT){return}if(show&&window.CURRENT_TOOLTIP_ELEMENT){return}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE!==element){return}element.TOOLTIP_HOVER_TIMEOUT=setTimeout(()=>{if(show){showTooltip(element)}else if(!element.TOOLTIP_FORCE_VISIBLE){hideTooltip(false)}},show?window.RUSTDOC_TOOLTIP_HOVER_MS:window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS)}function clearTooltipHoverTimeout(element){if(element.TOOLTIP_HOVER_TIMEOUT!==undefined){removeClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out");clearTimeout(element.TOOLTIP_HOVER_TIMEOUT);delete element.TOOLTIP_HOVER_TIMEOUT}}function tooltipBlurHandler(event){if(window.CURRENT_TOOLTIP_ELEMENT&&!elemIsInParent(document.activeElement,window.CURRENT_TOOLTIP_ELEMENT)&&!elemIsInParent(event.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT)&&!elemIsInParent(document.activeElement,window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE)&&!elemIsInParent(event.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE)){setTimeout(()=>hideTooltip(false),0)}}function hideTooltip(focus){if(window.CURRENT_TOOLTIP_ELEMENT){if(window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE){if(focus){window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.focus()}window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE=false}const body=document.getElementsByTagName("body")[0];body.removeChild(window.CURRENT_TOOLTIP_ELEMENT);clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);window.CURRENT_TOOLTIP_ELEMENT=null}}onEachLazy(document.getElementsByClassName("tooltip"),e=>{e.onclick=()=>{e.TOOLTIP_FORCE_VISIBLE=e.TOOLTIP_FORCE_VISIBLE?false:true;if(window.CURRENT_TOOLTIP_ELEMENT&&!e.TOOLTIP_FORCE_VISIBLE){hideTooltip(true)}else{showTooltip(e);window.CURRENT_TOOLTIP_ELEMENT.setAttribute("tabindex","0");window.CURRENT_TOOLTIP_ELEMENT.focus();window.CURRENT_TOOLTIP_ELEMENT.onblur=tooltipBlurHandler}return false};e.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointermove=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&!elemIsInParent(ev.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT)){setTooltipHoverTimeout(e,false);addClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out")}}});const sidebar_menu_toggle=document.getElementsByClassName("sidebar-menu-toggle")[0];if(sidebar_menu_toggle){sidebar_menu_toggle.addEventListener("click",()=>{const sidebar=document.getElementsByClassName("sidebar")[0];if(!hasClass(sidebar,"shown")){showSidebar()}else{hideSidebar()}})}function helpBlurHandler(event){blurHandler(event,getHelpButton(),window.hidePopoverMenus)}function buildHelpMenu(){const book_info=document.createElement("span");const channel=getVar("channel");book_info.className="top";book_info.innerHTML=`You can find more information in \ +the rustdoc book.`;const shortcuts=[["?","Show this help dialog"],["S","Focus the search field"],["↑","Move up in search results"],["↓","Move down in search results"],["← / →","Switch result tab (when results focused)"],["⏎","Go to active search result"],["+","Expand all sections"],["-","Collapse all sections"],].map(x=>"
"+x[0].split(" ").map((y,index)=>((index&1)===0?""+y+"":" "+y+" ")).join("")+"
"+x[1]+"
").join("");const div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="

Keyboard Shortcuts

"+shortcuts+"
";const infos=[`For a full list of all search features, take a look here.`,"Prefix searches with a type followed by a colon (e.g., fn:) to \ + restrict the search to a given item kind.","Accepted kinds are: fn, mod, struct, \ + enum, trait, type, macro, \ + and const.","Search functions by type signature (e.g., vec -> usize or \ + -> vec or String, enum:Cow -> bool)","You can look for items with an exact name by putting double quotes around \ + your request: \"string\"","Look for functions that accept or return \ + slices and \ + arrays by writing \ + square brackets (e.g., -> [u8] or [] -> Option)","Look for items inside another one by searching for a path: vec::Vec",].map(x=>"

"+x+"

").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="

Search Tricks

"+infos;const rustdoc_version=document.createElement("span");rustdoc_version.className="bottom";const rustdoc_version_code=document.createElement("code");rustdoc_version_code.innerText="rustdoc "+getVar("rustdoc-version");rustdoc_version.appendChild(rustdoc_version_code);const container=document.createElement("div");if(!isHelpPage){container.className="popover"}container.id="help";container.style.display="none";const side_by_side=document.createElement("div");side_by_side.className="side-by-side";side_by_side.appendChild(div_shortcuts);side_by_side.appendChild(div_infos);container.appendChild(book_info);container.appendChild(side_by_side);container.appendChild(rustdoc_version);if(isHelpPage){const help_section=document.createElement("section");help_section.appendChild(container);document.getElementById("main-content").appendChild(help_section);container.style.display="block"}else{const help_button=getHelpButton();help_button.appendChild(container);container.onblur=helpBlurHandler;help_button.onblur=helpBlurHandler;help_button.children[0].onblur=helpBlurHandler}return container}window.hideAllModals=switchFocus=>{hideSidebar();window.hidePopoverMenus();hideTooltip(switchFocus)};window.hidePopoverMenus=()=>{onEachLazy(document.querySelectorAll(".search-form .popover"),elem=>{elem.style.display="none"})};function getHelpMenu(buildNeeded){let menu=getHelpButton().querySelector(".popover");if(!menu&&buildNeeded){menu=buildHelpMenu()}return menu}function showHelp(){getHelpButton().querySelector("a").focus();const menu=getHelpMenu(true);if(menu.style.display==="none"){window.hideAllModals();menu.style.display=""}}if(isHelpPage){showHelp();document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault()})}else{document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault();const menu=getHelpMenu(true);const shouldShowHelp=menu.style.display==="none";if(shouldShowHelp){showHelp()}else{window.hidePopoverMenus()}})}setMobileTopbar();addSidebarItems();addSidebarCrates();onHashChange(null);window.addEventListener("hashchange",onHashChange);searchState.setup()}());(function(){let reset_button_timeout=null;const but=document.getElementById("copy-path");if(!but){return}but.onclick=()=>{const parent=but.parentElement;const path=[];onEach(parent.childNodes,child=>{if(child.tagName==="A"){path.push(child.textContent)}});const el=document.createElement("textarea");el.value=path.join("::");el.setAttribute("readonly","");el.style.position="absolute";el.style.left="-9999px";document.body.appendChild(el);el.select();document.execCommand("copy");document.body.removeChild(el);but.children[0].style.display="none";let tmp;if(but.childNodes.length<2){tmp=document.createTextNode("✓");but.appendChild(tmp)}else{onEachLazy(but.childNodes,e=>{if(e.nodeType===Node.TEXT_NODE){tmp=e;return true}});tmp.textContent="✓"}if(reset_button_timeout!==null){window.clearTimeout(reset_button_timeout)}function reset_button(){tmp.textContent="";reset_button_timeout=null;but.children[0].style.display=""}reset_button_timeout=window.setTimeout(reset_button,1000)}}()) \ No newline at end of file diff --git a/static.files/normalize-76eba96aa4d2e634.css b/static.files/normalize-76eba96aa4d2e634.css new file mode 100644 index 00000000..469959f1 --- /dev/null +++ b/static.files/normalize-76eba96aa4d2e634.css @@ -0,0 +1,2 @@ + /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ +html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type="button"],[type="reset"],[type="submit"],button{-webkit-appearance:button}[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none} \ No newline at end of file diff --git a/static.files/noscript-5d8b3c7633ad77ba.css b/static.files/noscript-5d8b3c7633ad77ba.css new file mode 100644 index 00000000..8c63ef06 --- /dev/null +++ b/static.files/noscript-5d8b3c7633ad77ba.css @@ -0,0 +1 @@ + #main-content .attributes{margin-left:0 !important;}#copy-path{display:none;}nav.sub{display:none;}.src .sidebar{display:none;}.notable-traits{display:none;}:root{--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#f5f5f5;--sidebar-background-color-hover:#e0e0e0;--code-block-background-color:#f5f5f5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#fff;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#f5f5f5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);}@media (prefers-color-scheme:dark){:root{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2a2a2a;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);}} \ No newline at end of file diff --git a/static.files/rust-logo-151179464ae7ed46.svg b/static.files/rust-logo-151179464ae7ed46.svg new file mode 100644 index 00000000..62424d8f --- /dev/null +++ b/static.files/rust-logo-151179464ae7ed46.svg @@ -0,0 +1,61 @@ + + + diff --git a/static.files/rustdoc-9ee3a5e31a2afa3e.css b/static.files/rustdoc-9ee3a5e31a2afa3e.css new file mode 100644 index 00000000..8749d0eb --- /dev/null +++ b/static.files/rustdoc-9ee3a5e31a2afa3e.css @@ -0,0 +1,10 @@ + :root{--nav-sub-mobile-padding:8px;--search-typename-width:6.75rem;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular-018c141bf0843ffd.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium-8f9a781e4970d388.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:400;src:local('Source Serif 4'),url("SourceSerif4-Regular-46f98efaafac5295.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:italic;font-weight:400;src:local('Source Serif 4 Italic'),url("SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:700;src:local('Source Serif 4 Bold'),url("SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:italic;font-weight:400;src:url("SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'NanumBarunGothic';src:url("NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2") format("woff2");font-display:swap;unicode-range:U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF;}*{box-sizing:border-box;}body{font:1rem/1.5 "Source Serif 4",NanumBarunGothic,serif;margin:0;position:relative;overflow-wrap:break-word;overflow-wrap:anywhere;font-feature-settings:"kern","liga";background-color:var(--main-background-color);color:var(--main-color);}h1{font-size:1.5rem;}h2{font-size:1.375rem;}h3{font-size:1.25rem;}h1,h2,h3,h4,h5,h6{font-weight:500;}h1,h2,h3,h4{margin:25px 0 15px 0;padding-bottom:6px;}.docblock h3,.docblock h4,h5,h6{margin:15px 0 5px 0;}.docblock>h2:first-child,.docblock>h3:first-child,.docblock>h4:first-child,.docblock>h5:first-child,.docblock>h6:first-child{margin-top:0;}.main-heading h1{margin:0;padding:0;flex-grow:1;overflow-wrap:break-word;overflow-wrap:anywhere;}.main-heading{display:flex;flex-wrap:wrap;padding-bottom:6px;margin-bottom:15px;}.content h2,.top-doc .docblock>h3,.top-doc .docblock>h4{border-bottom:1px solid var(--headings-border-bottom-color);}h1,h2{line-height:1.25;padding-top:3px;padding-bottom:9px;}h3.code-header{font-size:1.125rem;}h4.code-header{font-size:1rem;}.code-header{font-weight:600;margin:0;padding:0;white-space:pre-wrap;}#crate-search,h1,h2,h3,h4,h5,h6,.sidebar,.mobile-topbar,.search-input,.search-results .result-name,.item-name>a,.out-of-band,span.since,a.src,#help-button>a,summary.hideme,.scraped-example-list,ul.all-items{font-family:"Fira Sans",Arial,NanumBarunGothic,sans-serif;}#toggle-all-docs,a.anchor,.small-section-header a,#src-sidebar a,.rust a,.sidebar h2 a,.sidebar h3 a,.mobile-topbar h2 a,h1 a,.search-results a,.stab,.result-name i{color:var(--main-color);}span.enum,a.enum,span.struct,a.struct,span.union,a.union,span.primitive,a.primitive,span.type,a.type,span.foreigntype,a.foreigntype{color:var(--type-link-color);}span.trait,a.trait,span.traitalias,a.traitalias{color:var(--trait-link-color);}span.associatedtype,a.associatedtype,span.constant,a.constant,span.static,a.static{color:var(--assoc-item-link-color);}span.fn,a.fn,span.method,a.method,span.tymethod,a.tymethod{color:var(--function-link-color);}span.attr,a.attr,span.derive,a.derive,span.macro,a.macro{color:var(--macro-link-color);}span.mod,a.mod{color:var(--mod-link-color);}span.keyword,a.keyword{color:var(--keyword-link-color);}a{color:var(--link-color);text-decoration:none;}ol,ul{padding-left:24px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.625em;}p,.docblock>.warning{margin:0 0 .75em 0;}p:last-child,.docblock>.warning:last-child{margin:0;}button{padding:1px 6px;cursor:pointer;}button#toggle-all-docs{padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.rustdoc{display:flex;flex-direction:row;flex-wrap:nowrap;}main{position:relative;flex-grow:1;padding:10px 15px 40px 45px;min-width:0;}.src main{padding:15px;}.width-limiter{max-width:960px;margin-right:auto;}details:not(.toggle) summary{margin-bottom:.6em;}code,pre,a.test-arrow,.code-header{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.125em;}.docblock pre code,.docblock-short pre code{padding:0;}pre{padding:14px;line-height:1.5;}pre.item-decl{overflow-x:auto;}.item-decl .type-contents-toggle{contain:initial;}.src .content pre{padding:20px;}.rustdoc.src .example-wrap pre.src-line-numbers{padding:20px 0 20px 4px;}img{max-width:100%;}.sub-logo-container,.logo-container{line-height:0;display:block;}.sub-logo-container{margin-right:32px;}.sub-logo-container>img{height:60px;width:60px;object-fit:contain;}.rust-logo{filter:var(--rust-logo-filter);}.sidebar{font-size:0.875rem;flex:0 0 200px;overflow-y:scroll;overscroll-behavior:contain;position:sticky;height:100vh;top:0;left:0;}.rustdoc.src .sidebar{flex-basis:50px;border-right:1px solid;overflow-x:hidden;overflow-y:hidden;z-index:1;}.sidebar,.mobile-topbar,.sidebar-menu-toggle,#src-sidebar-toggle,#src-sidebar{background-color:var(--sidebar-background-color);}#src-sidebar-toggle>button:hover,#src-sidebar-toggle>button:focus{background-color:var(--sidebar-background-color-hover);}.src .sidebar>*:not(#src-sidebar-toggle){visibility:hidden;}.src-sidebar-expanded .src .sidebar{overflow-y:auto;flex-basis:300px;}.src-sidebar-expanded .src .sidebar>*:not(#src-sidebar-toggle){visibility:visible;}#all-types{margin-top:1em;}*{scrollbar-width:initial;scrollbar-color:var(--scrollbar-color);}.sidebar{scrollbar-width:thin;scrollbar-color:var(--scrollbar-color);}::-webkit-scrollbar{width:12px;}.sidebar::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0;background-color:var(--scrollbar-track-background-color);}.sidebar::-webkit-scrollbar-track{background-color:var(--scrollbar-track-background-color);}::-webkit-scrollbar-thumb,.sidebar::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb-background-color);}.hidden{display:none !important;}.logo-container>img{height:48px;width:48px;}ul.block,.block li{padding:0;margin:0;list-style:none;}.sidebar-elems a,.sidebar>h2 a{display:block;padding:0.25rem;margin-left:-0.25rem;}.sidebar h2{overflow-wrap:anywhere;padding:0;margin:0.7rem 0;}.sidebar h3{font-size:1.125rem;padding:0;margin:0;}.sidebar-elems,.sidebar>.version,.sidebar>h2{padding-left:24px;}.sidebar a{color:var(--sidebar-link-color);}.sidebar .current,.sidebar .current a,.sidebar-crate a.logo-container:hover+h2 a,.sidebar a:hover:not(.logo-container){background-color:var(--sidebar-current-link-background-color);}.sidebar-elems .block{margin-bottom:2em;}.sidebar-elems .block li a{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}.sidebar-crate{display:flex;align-items:center;justify-content:center;margin:14px 32px 1rem;row-gap:10px;column-gap:32px;flex-wrap:wrap;}.sidebar-crate h2{flex-grow:1;margin:0 -8px;align-self:start;}.sidebar-crate .logo-container{margin:0 -16px 0 -16px;text-align:center;}.sidebar-crate h2 a{display:block;margin:0 calc(-24px + 0.25rem) 0 -0.5rem;padding:calc((16px - 0.57rem ) / 2 ) 0.25rem;padding-left:0.5rem;}.sidebar-crate h2 .version{display:block;font-weight:normal;font-size:1rem;overflow-wrap:break-word;margin-top:calc((-16px + 0.57rem ) / 2 );}.sidebar-crate+.version{margin-top:-1rem;margin-bottom:1rem;}.mobile-topbar{display:none;}.rustdoc .example-wrap{display:flex;position:relative;margin-bottom:10px;}.rustdoc .example-wrap:last-child{margin-bottom:0px;}.rustdoc .example-wrap pre{margin:0;flex-grow:1;}.rustdoc:not(.src) .example-wrap pre{overflow:auto hidden;}.rustdoc .example-wrap pre.example-line-numbers,.rustdoc .example-wrap pre.src-line-numbers{flex-grow:0;min-width:fit-content;overflow:initial;text-align:right;-webkit-user-select:none;user-select:none;padding:14px 8px;color:var(--src-line-numbers-span-color);}.rustdoc .example-wrap pre.src-line-numbers{padding:14px 0;}.src-line-numbers a,.src-line-numbers span{color:var(--src-line-numbers-span-color);padding:0 8px;}.src-line-numbers :target{background-color:transparent;border-right:none;padding:0 8px;}.src-line-numbers .line-highlighted{background-color:var(--src-line-number-highlighted-background-color);}.search-loading{text-align:center;}.docblock-short{overflow-wrap:break-word;overflow-wrap:anywhere;}.docblock :not(pre)>code,.docblock-short code{white-space:pre-wrap;}.top-doc .docblock h2{font-size:1.375rem;}.top-doc .docblock h3{font-size:1.25rem;}.top-doc .docblock h4,.top-doc .docblock h5{font-size:1.125rem;}.top-doc .docblock h6{font-size:1rem;}.docblock h5{font-size:1rem;}.docblock h6{font-size:0.875rem;}.docblock{margin-left:24px;position:relative;}.docblock>:not(.more-examples-toggle):not(.example-wrap){max-width:100%;overflow-x:auto;}.out-of-band{flex-grow:0;font-size:1.125rem;}.docblock code,.docblock-short code,pre,.rustdoc.src .example-wrap{background-color:var(--code-block-background-color);}#main-content{position:relative;}.docblock table{margin:.5em 0;border-collapse:collapse;}.docblock table td,.docblock table th{padding:.5em;border:1px solid var(--border-color);}.docblock table tbody tr:nth-child(2n){background:var(--table-alt-row-background-color);}.method .where,.fn .where,.where.fmt-newline{display:block;white-space:pre-wrap;font-size:0.875rem;}.item-info{display:block;margin-left:24px;}.item-info code{font-size:0.875rem;}#main-content>.item-info{margin-left:0;}nav.sub{flex-grow:1;flex-flow:row nowrap;margin:4px 0 25px 0;display:flex;align-items:center;}.search-form{position:relative;display:flex;height:34px;flex-grow:1;}.src nav.sub{margin:0 0 15px 0;}.small-section-header{display:block;position:relative;}.small-section-header:hover>.anchor,.impl:hover>.anchor,.trait-impl:hover>.anchor,.variant:hover>.anchor{display:initial;}.anchor{display:none;position:absolute;left:-0.5em;background:none !important;}.anchor.field{left:-5px;}.small-section-header>.anchor{left:-15px;padding-right:8px;}h2.small-section-header>.anchor{padding-right:6px;}.main-heading a:hover,.example-wrap .rust a:hover,.all-items a:hover,.docblock a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.docblock-short a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.item-info a{text-decoration:underline;}.crate.block a.current{font-weight:500;}table,.item-table{overflow-wrap:break-word;}.item-table{display:table;padding:0;margin:0;}.item-table>li{display:table-row;}.item-table>li>div{display:table-cell;}.item-table>li>.item-name{padding-right:1.25rem;}.search-results-title{margin-top:0;white-space:nowrap;display:flex;align-items:baseline;}#crate-search-div{position:relative;min-width:5em;}#crate-search{min-width:115px;padding:0 23px 0 4px;max-width:100%;text-overflow:ellipsis;border:1px solid var(--border-color);border-radius:4px;outline:none;cursor:pointer;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;background-color:var(--main-background-color);color:inherit;line-height:1.5;font-weight:500;}#crate-search:hover,#crate-search:focus{border-color:var(--crate-search-hover-border);}#crate-search-div::after{pointer-events:none;width:100%;height:100%;position:absolute;top:0;left:0;content:"";background-repeat:no-repeat;background-size:20px;background-position:calc(100% - 2px) 56%;background-image:url('data:image/svg+xml, \ + ');filter:var(--crate-search-div-filter);}#crate-search-div:hover::after,#crate-search-div:focus-within::after{filter:var(--crate-search-div-hover-filter);}#crate-search>option{font-size:1rem;}.search-input{-webkit-appearance:none;outline:none;border:1px solid var(--border-color);border-radius:2px;padding:8px;font-size:1rem;flex-grow:1;background-color:var(--button-background-color);color:var(--search-color);}.search-input:focus{border-color:var(--search-input-focused-border-color);}.search-results{display:none;}.search-results.active{display:block;}.search-results>a{display:flex;margin-left:2px;margin-right:2px;border-bottom:1px solid var(--search-result-border-color);gap:1em;}.search-results>a>div.desc{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex:2;}.search-results a:hover,.search-results a:focus{background-color:var(--search-result-link-focus-background-color);}.search-results .result-name{display:flex;align-items:center;justify-content:start;flex:3;}.search-results .result-name .alias{color:var(--search-results-alias-color);}.search-results .result-name .grey{color:var(--search-results-grey-color);}.search-results .result-name .typename{color:var(--search-results-grey-color);font-size:0.875rem;width:var(--search-typename-width);}.search-results .result-name .path{word-break:break-all;max-width:calc(100% - var(--search-typename-width));display:inline-block;}.search-results .result-name .path>*{display:inline;}.popover{position:absolute;top:100%;right:0;z-index:2;margin-top:7px;border-radius:3px;border:1px solid var(--border-color);background-color:var(--main-background-color);color:var(--main-color);--popover-arrow-offset:11px;}.popover::before{content:'';position:absolute;right:var(--popover-arrow-offset);border:solid var(--border-color);border-width:1px 1px 0 0;background-color:var(--main-background-color);padding:4px;transform:rotate(-45deg);top:-5px;}.setting-line{margin:1.2em 0.6em;}.setting-radio input,.setting-check input{margin-right:0.3em;height:1.2rem;width:1.2rem;border:2px solid var(--settings-input-border-color);outline:none;-webkit-appearance:none;cursor:pointer;}.setting-radio input{border-radius:50%;}.setting-radio span,.setting-check span{padding-bottom:1px;}.setting-radio{margin-top:0.1em;margin-bottom:0.1em;min-width:3.8em;padding:0.3em;display:inline-flex;align-items:center;cursor:pointer;}.setting-radio+.setting-radio{margin-left:0.5em;}.setting-check{margin-right:20px;display:flex;align-items:center;cursor:pointer;}.setting-radio input:checked{box-shadow:inset 0 0 0 3px var(--main-background-color);background-color:var(--settings-input-color);}.setting-check input:checked{background-color:var(--settings-input-color);border-width:1px;content:url('data:image/svg+xml,\ + \ + ');}.setting-radio input:focus,.setting-check input:focus{box-shadow:0 0 1px 1px var(--settings-input-color);}.setting-radio input:checked:focus{box-shadow:inset 0 0 0 3px var(--main-background-color),0 0 2px 2px var(--settings-input-color);}.setting-radio input:hover,.setting-check input:hover{border-color:var(--settings-input-color) !important;}#help.popover{max-width:600px;--popover-arrow-offset:48px;}#help dt{float:left;clear:left;margin-right:0.5rem;}#help span.top,#help span.bottom{text-align:center;display:block;font-size:1.125rem;}#help span.top{margin:10px 0;border-bottom:1px solid var(--border-color);padding-bottom:4px;margin-bottom:6px;}#help span.bottom{clear:both;border-top:1px solid var(--border-color);}.side-by-side>div{width:50%;float:left;padding:0 20px 20px 17px;}.item-info .stab{min-height:36px;display:flex;padding:3px;margin-bottom:5px;align-items:center;vertical-align:text-bottom;}.item-name .stab{margin-left:0.3125em;}.stab{padding:0 2px;font-size:0.875rem;font-weight:normal;color:var(--main-color);background-color:var(--stab-background-color);width:fit-content;white-space:pre-wrap;border-radius:3px;display:inline;vertical-align:baseline;}.stab.portability>code{background:none;color:var(--stab-code-color);}.stab .emoji{font-size:1.25rem;margin-right:0.3rem;}.emoji{text-shadow:1px 0 0 black,-1px 0 0 black,0 1px 0 black,0 -1px 0 black;}.since{font-weight:normal;font-size:initial;}.rightside{padding-left:12px;float:right;}.rightside:not(a),.out-of-band{color:var(--right-side-color);}pre.rust{tab-size:4;-moz-tab-size:4;}pre.rust .kw{color:var(--code-highlight-kw-color);}pre.rust .kw-2{color:var(--code-highlight-kw-2-color);}pre.rust .lifetime{color:var(--code-highlight-lifetime-color);}pre.rust .prelude-ty{color:var(--code-highlight-prelude-color);}pre.rust .prelude-val{color:var(--code-highlight-prelude-val-color);}pre.rust .string{color:var(--code-highlight-string-color);}pre.rust .number{color:var(--code-highlight-number-color);}pre.rust .bool-val{color:var(--code-highlight-literal-color);}pre.rust .self{color:var(--code-highlight-self-color);}pre.rust .attr{color:var(--code-highlight-attribute-color);}pre.rust .macro,pre.rust .macro-nonterminal{color:var(--code-highlight-macro-color);}pre.rust .question-mark{font-weight:bold;color:var(--code-highlight-question-mark-color);}pre.rust .comment{color:var(--code-highlight-comment-color);}pre.rust .doccomment{color:var(--code-highlight-doc-comment-color);}.rustdoc.src .example-wrap pre.rust a{background:var(--codeblock-link-background);}.example-wrap.compile_fail,.example-wrap.should_panic{border-left:2px solid var(--codeblock-error-color);}.ignore.example-wrap{border-left:2px solid var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover,.example-wrap.should_panic:hover{border-left:2px solid var(--codeblock-error-hover-color);}.example-wrap.ignore:hover{border-left:2px solid var(--codeblock-ignore-hover-color);}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip{color:var(--codeblock-error-color);}.example-wrap.ignore .tooltip{color:var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover .tooltip,.example-wrap.should_panic:hover .tooltip{color:var(--codeblock-error-hover-color);}.example-wrap.ignore:hover .tooltip{color:var(--codeblock-ignore-hover-color);}.example-wrap .tooltip{position:absolute;display:block;left:-25px;top:5px;margin:0;line-height:1;}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip,.example-wrap.ignore .tooltip{font-weight:bold;font-size:1.25rem;}.content .docblock .warning{border-left:2px solid var(--warning-border-color);padding:14px;position:relative;overflow-x:visible !important;}.content .docblock .warning::before{color:var(--warning-border-color);content:"ⓘ";position:absolute;left:-25px;top:5px;font-weight:bold;font-size:1.25rem;}a.test-arrow{visibility:hidden;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:1.375rem;top:5px;right:5px;z-index:1;color:var(--test-arrow-color);background-color:var(--test-arrow-background-color);}a.test-arrow:hover{color:var(--test-arrow-hover-color);background-color:var(--test-arrow-hover-background-color);}.example-wrap:hover .test-arrow{visibility:visible;}.code-attribute{font-weight:300;color:var(--code-attribute-color);}.item-spacer{width:100%;height:12px;display:block;}.out-of-band>span.since{font-size:1.25rem;}.sub-variant h4{font-size:1rem;font-weight:400;margin-top:0;margin-bottom:0;}.sub-variant{margin-left:24px;margin-bottom:40px;}.sub-variant>.sub-variant-field{margin-left:24px;}:target{padding-right:3px;background-color:var(--target-background-color);border-right:3px solid var(--target-border-color);}.code-header a.tooltip{color:inherit;margin-right:15px;position:relative;}.code-header a.tooltip:hover{color:var(--link-color);}a.tooltip:hover::after{position:absolute;top:calc(100% - 10px);left:-15px;right:-15px;height:20px;content:"\00a0";}.fade-out{opacity:0;transition:opacity 0.45s cubic-bezier(0,0,0.1,1.0);}.popover.tooltip .content{margin:0.25em 0.5em;}.popover.tooltip .content pre,.popover.tooltip .content code{background:transparent;margin:0;padding:0;font-size:1.25rem;white-space:pre-wrap;}.popover.tooltip .content>h3:first-child{margin:0 0 5px 0;}.search-failed{text-align:center;margin-top:20px;display:none;}.search-failed.active{display:block;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#search-tabs{display:flex;flex-direction:row;gap:1px;margin-bottom:4px;}#search-tabs button{text-align:center;font-size:1.125rem;border:0;border-top:2px solid;flex:1;line-height:1.5;color:inherit;}#search-tabs button:not(.selected){background-color:var(--search-tab-button-not-selected-background);border-top-color:var(--search-tab-button-not-selected-border-top-color);}#search-tabs button:hover,#search-tabs button.selected{background-color:var(--search-tab-button-selected-background);border-top-color:var(--search-tab-button-selected-border-top-color);}#search-tabs .count{font-size:1rem;font-variant-numeric:tabular-nums;color:var(--search-tab-title-count-color);}#search .error code{border-radius:3px;background-color:var(--search-error-code-background-color);}.search-corrections{font-weight:normal;}#src-sidebar-toggle{position:sticky;top:0;left:0;font-size:1.25rem;border-bottom:1px solid;display:flex;height:40px;justify-content:stretch;align-items:stretch;z-index:10;}#src-sidebar{width:100%;overflow:auto;}#src-sidebar>.title{font-size:1.5rem;text-align:center;border-bottom:1px solid var(--border-color);margin-bottom:6px;}#src-sidebar div.files>a:hover,details.dir-entry summary:hover,#src-sidebar div.files>a:focus,details.dir-entry summary:focus{background-color:var(--src-sidebar-background-hover);}#src-sidebar div.files>a.selected{background-color:var(--src-sidebar-background-selected);}#src-sidebar-toggle>button{font-size:inherit;font-weight:bold;background:none;color:inherit;text-align:center;border:none;outline:none;flex:1 1;-webkit-appearance:none;opacity:1;}#settings-menu,#help-button{margin-left:4px;display:flex;}#settings-menu>a,#help-button>a{display:flex;align-items:center;justify-content:center;background-color:var(--button-background-color);border:1px solid var(--border-color);border-radius:2px;color:var(--settings-button-color);font-size:20px;width:33px;}#settings-menu>a:hover,#settings-menu>a:focus,#help-button>a:hover,#help-button>a:focus{border-color:var(--settings-button-border-focus);}#copy-path{color:var(--copy-path-button-color);background:var(--main-background-color);height:34px;margin-left:10px;padding:0;padding-left:2px;border:0;width:33px;}#copy-path>img{filter:var(--copy-path-img-filter);}#copy-path:hover>img{filter:var(--copy-path-img-hover-filter);}@keyframes rotating{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}#settings-menu.rotate>a img{animation:rotating 2s linear infinite;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px var(--border-color);border-radius:3px;color:var(--kbd-color);background-color:var(--kbd-background);box-shadow:inset 0 -1px 0 var(--kbd-box-shadow-color);}ul.all-items>li{list-style:none;}details.dir-entry{padding-left:4px;}details.dir-entry>summary{margin:0 0 0 -4px;padding:0 0 0 4px;cursor:pointer;}details.dir-entry div.folders,details.dir-entry div.files{padding-left:23px;}details.dir-entry a{display:block;}details.toggle{contain:layout;position:relative;}details.toggle>summary.hideme{cursor:pointer;font-size:1rem;}details.toggle>summary{list-style:none;outline:none;}details.toggle>summary::-webkit-details-marker,details.toggle>summary::marker{display:none;}details.toggle>summary.hideme>span{margin-left:9px;}details.toggle>summary::before{background:url('data:image/svg+xml,') no-repeat top left;content:"";cursor:pointer;width:16px;height:16px;display:inline-block;vertical-align:middle;opacity:.5;filter:var(--toggle-filter);}details.toggle>summary.hideme>span,.more-examples-toggle summary,.more-examples-toggle .hide-more{color:var(--toggles-color);}details.toggle>summary::after{content:"Expand";overflow:hidden;width:0;height:0;position:absolute;}details.toggle>summary.hideme::after{content:"";}details.toggle>summary:focus::before,details.toggle>summary:hover::before{opacity:1;}details.toggle>summary:focus-visible::before{outline:1px dotted #000;outline-offset:1px;}details.non-exhaustive{margin-bottom:8px;}details.toggle>summary.hideme::before{position:relative;}details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;top:4px;}.impl-items>details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;}details.toggle[open] >summary.hideme{position:absolute;}details.toggle[open] >summary.hideme>span{display:none;}details.toggle[open] >summary::before{background:url('data:image/svg+xml,') no-repeat top left;}details.toggle[open] >summary::after{content:"Collapse";}.docblock summary>*{display:inline-block;}.docblock>.example-wrap:first-child .tooltip{margin-top:16px;}@media (max-width:850px){#search-tabs .count{display:block;}}@media (max-width:700px){*[id]{scroll-margin-top:45px;}.rustdoc{display:block;}main{padding-left:15px;padding-top:0px;}.main-heading{flex-direction:column;}.out-of-band{text-align:left;margin-left:initial;padding:initial;}.out-of-band .since::before{content:"Since ";}.sidebar .logo-container,.sidebar .location{display:none;}.sidebar{position:fixed;top:45px;left:-1000px;z-index:11;height:calc(100vh - 45px);width:200px;}.src main,.rustdoc.src .sidebar{top:0;padding:0;height:100vh;border:0;}.sidebar.shown,.src-sidebar-expanded .src .sidebar,.rustdoc:not(.src) .sidebar:focus-within{left:0;}.mobile-topbar h2{padding-bottom:0;margin:auto 0.5em auto auto;overflow:hidden;font-size:24px;}.mobile-topbar h2 a{display:block;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;}.mobile-topbar .logo-container>img{max-width:35px;max-height:35px;margin:5px 0 5px 20px;}.mobile-topbar{display:flex;flex-direction:row;position:sticky;z-index:10;font-size:2rem;height:45px;width:100%;left:0;top:0;}.sidebar-menu-toggle{width:45px;font-size:32px;border:none;color:var(--main-color);}.sidebar-elems{margin-top:1em;}.anchor{display:none !important;}#main-content>details.toggle>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}#src-sidebar-toggle{position:fixed;left:1px;top:100px;width:30px;font-size:1.5rem;padding:0;z-index:10;border-top-right-radius:3px;border-bottom-right-radius:3px;border:1px solid;border-left:0;}.src-sidebar-expanded #src-sidebar-toggle{left:unset;top:unset;width:unset;border-top-right-radius:unset;border-bottom-right-radius:unset;position:sticky;border:0;border-bottom:1px solid;}#copy-path,#help-button{display:none;}.item-table,.item-row,.item-table>li,.item-table>li>div,.search-results>a,.search-results>a>div{display:block;}.search-results>a{padding:5px 0px;}.search-results>a>div.desc,.item-table>li>div.desc{padding-left:2em;}.search-results .result-name{display:block;}.search-results .result-name .typename{width:initial;margin-right:0;}.search-results .result-name .typename,.search-results .result-name .path{display:inline;}.src-sidebar-expanded .src .sidebar{max-width:100vw;width:100vw;}details.toggle:not(.top-doc)>summary{margin-left:10px;}.impl-items>details.toggle>summary:not(.hideme)::before,#main-content>details.toggle:not(.top-doc)>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}.impl-items>.item-info{margin-left:34px;}.src nav.sub{margin:0;padding:var(--nav-sub-mobile-padding);}}@media (min-width:701px){.scraped-example-title{position:absolute;z-index:10;background:var(--main-background-color);bottom:8px;right:5px;padding:2px 4px;box-shadow:0 0 4px var(--main-background-color);}}@media print{nav.sidebar,nav.sub,.out-of-band,a.src,#copy-path,details.toggle[open] >summary::before,details.toggle>summary::before,details.toggle.top-doc>summary{display:none;}.docblock{margin-left:0;}main{padding:10px;}}@media (max-width:464px){.docblock{margin-left:12px;}.docblock code{overflow-wrap:break-word;overflow-wrap:anywhere;}nav.sub{flex-direction:column;}.search-form{align-self:stretch;}.sub-logo-container>img{height:35px;width:35px;margin-bottom:var(--nav-sub-mobile-padding);}}.variant,.implementors-toggle>summary,.impl,#implementors-list>.docblock,.impl-items>section,.impl-items>.toggle>summary,.methods>section,.methods>.toggle>summary{margin-bottom:0.75em;}.variants>.docblock,.implementors-toggle>.docblock,.impl-items>.toggle[open]:not(:last-child),.methods>.toggle[open]:not(:last-child),.implementors-toggle[open]:not(:last-child){margin-bottom:2em;}#trait-implementations-list .impl-items>.toggle:not(:last-child),#synthetic-implementations-list .impl-items>.toggle:not(:last-child),#blanket-implementations-list .impl-items>.toggle:not(:last-child){margin-bottom:1em;}.scraped-example-list .scrape-help{margin-left:10px;padding:0 4px;font-weight:normal;font-size:12px;position:relative;bottom:1px;border:1px solid var(--scrape-example-help-border-color);border-radius:50px;color:var(--scrape-example-help-color);}.scraped-example-list .scrape-help:hover{border-color:var(--scrape-example-help-hover-border-color);color:var(--scrape-example-help-hover-color);}.scraped-example{position:relative;}.scraped-example .code-wrapper{position:relative;display:flex;flex-direction:row;flex-wrap:wrap;width:100%;}.scraped-example:not(.expanded) .code-wrapper{max-height:calc(1.5em * 5 + 10px);}.scraped-example:not(.expanded) .code-wrapper pre{overflow-y:hidden;padding-bottom:0;max-height:calc(1.5em * 5 + 10px);}.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper,.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre{max-height:calc(1.5em * 10 + 10px);}.scraped-example .code-wrapper .next,.scraped-example .code-wrapper .prev,.scraped-example .code-wrapper .expand{color:var(--main-color);position:absolute;top:0.25em;z-index:1;padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.scraped-example .code-wrapper .prev{right:2.25em;}.scraped-example .code-wrapper .next{right:1.25em;}.scraped-example .code-wrapper .expand{right:0.25em;}.scraped-example:not(.expanded) .code-wrapper::before,.scraped-example:not(.expanded) .code-wrapper::after{content:" ";width:100%;height:5px;position:absolute;z-index:1;}.scraped-example:not(.expanded) .code-wrapper::before{top:0;background:linear-gradient(to bottom,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example:not(.expanded) .code-wrapper::after{bottom:0;background:linear-gradient(to top,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example .code-wrapper .example-wrap{width:100%;overflow-y:hidden;margin-bottom:0;}.scraped-example:not(.expanded) .code-wrapper .example-wrap{overflow-x:hidden;}.scraped-example .example-wrap .rust span.highlight{background:var(--scrape-example-code-line-highlight);}.scraped-example .example-wrap .rust span.highlight.focus{background:var(--scrape-example-code-line-highlight-focus);}.more-examples-toggle{max-width:calc(100% + 25px);margin-top:10px;margin-left:-25px;}.more-examples-toggle .hide-more{margin-left:25px;cursor:pointer;}.more-scraped-examples{margin-left:25px;position:relative;}.toggle-line{position:absolute;top:5px;bottom:0;right:calc(100% + 10px);padding:0 4px;cursor:pointer;}.toggle-line-inner{min-width:2px;height:100%;background:var(--scrape-example-toggle-line-background);}.toggle-line:hover .toggle-line-inner{background:var(--scrape-example-toggle-line-hover-background);}.more-scraped-examples .scraped-example,.example-links{margin-top:20px;}.more-scraped-examples .scraped-example:first-child{margin-top:5px;}.example-links ul{margin-bottom:0;}:root[data-theme="light"]{--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#f5f5f5;--sidebar-background-color-hover:#e0e0e0;--code-block-background-color:#f5f5f5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#fff;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#f5f5f5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);}:root[data-theme="dark"]{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2a2a2a;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);}:root[data-theme="ayu"]{--main-background-color:#0f1419;--main-color:#c5c5c5;--settings-input-color:#ffb454;--settings-input-border-color:#999;--settings-button-color:#fff;--settings-button-border-focus:#e0e0e0;--sidebar-background-color:#14191f;--sidebar-background-color-hover:rgba(70,70,70,0.33);--code-block-background-color:#191f26;--scrollbar-track-background-color:transparent;--scrollbar-thumb-background-color:#5c6773;--scrollbar-color:#5c6773 #24292f;--headings-border-bottom-color:#5c6773;--border-color:#5c6773;--button-background-color:#141920;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#5c6773;--copy-path-button-color:#fff;--copy-path-img-filter:invert(70%);--copy-path-img-hover-filter:invert(100%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ffa0a5;--trait-link-color:#39afd7;--assoc-item-link-color:#39afd7;--function-link-color:#fdd687;--macro-link-color:#a37acc;--keyword-link-color:#39afd7;--mod-link-color:#39afd7;--link-color:#39afd7;--sidebar-link-color:#53b1db;--sidebar-current-link-background-color:transparent;--search-result-link-focus-background-color:#3c3c3c;--search-result-border-color:#aaa3;--search-color:#fff;--search-error-code-background-color:#4f4c4c;--search-results-alias-color:#c5c5c5;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:none;--search-tab-button-not-selected-background:transparent !important;--search-tab-button-selected-border-top-color:none;--search-tab-button-selected-background:#141920 !important;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ff7733;--code-highlight-kw-2-color:#ff7733;--code-highlight-lifetime-color:#ff7733;--code-highlight-prelude-color:#69f2df;--code-highlight-prelude-val-color:#ff7733;--code-highlight-number-color:#b8cc52;--code-highlight-string-color:#b8cc52;--code-highlight-literal-color:#ff7733;--code-highlight-attribute-color:#e6e1cf;--code-highlight-self-color:#36a3d9;--code-highlight-macro-color:#a37acc;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#788797;--code-highlight-doc-comment-color:#a1ac88;--src-line-numbers-span-color:#5c6773;--src-line-number-highlighted-background-color:rgba(255,236,164,0.06);--test-arrow-color:#788797;--test-arrow-background-color:rgba(57,175,215,0.09);--test-arrow-hover-color:#c5c5c5;--test-arrow-hover-background-color:rgba(57,175,215,0.368);--target-background-color:rgba(255,236,164,0.06);--target-border-color:rgba(255,180,76,0.85);--kbd-color:#c5c5c5;--kbd-background:#314559;--kbd-box-shadow-color:#5c6773;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg) brightness(94%) contrast(94%);--crate-search-div-hover-filter:invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg) brightness(113%) contrast(76%);--crate-search-hover-border:#e0e0e0;--src-sidebar-background-selected:#14191f;--src-sidebar-background-hover:#14191f;--table-alt-row-background-color:#191f26;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(15,20,25,1);--scrape-example-code-wrapper-background-end:rgba(15,20,25,0);}:root[data-theme="ayu"] h1,:root[data-theme="ayu"] h2,:root[data-theme="ayu"] h3,:root[data-theme="ayu"] h4,:where(:root[data-theme="ayu"]) h1 a,:root[data-theme="ayu"] .sidebar h2 a,:root[data-theme="ayu"] .sidebar h3 a,:root[data-theme="ayu"] #source-sidebar>.title{color:#fff;}:root[data-theme="ayu"] .docblock code{color:#ffb454;}:root[data-theme="ayu"] .docblock a>code{color:#39AFD7 !important;}:root[data-theme="ayu"] .code-header,:root[data-theme="ayu"] .docblock pre>code,:root[data-theme="ayu"] pre,:root[data-theme="ayu"] pre>code,:root[data-theme="ayu"] .item-info code,:root[data-theme="ayu"] .rustdoc.source .example-wrap{color:#e6e1cf;}:root[data-theme="ayu"] .sidebar .current,:root[data-theme="ayu"] .sidebar a:hover,:root[data-theme="ayu"] #src-sidebar div.files>a:hover,:root[data-theme="ayu"] details.dir-entry summary:hover,:root[data-theme="ayu"] #src-sidebar div.files>a:focus,:root[data-theme="ayu"] details.dir-entry summary:focus,:root[data-theme="ayu"] #src-sidebar div.files>a.selected{color:#ffb44c;}:root[data-theme="ayu"] .sidebar-elems .location{color:#ff7733;}:root[data-theme="ayu"] .src-line-numbers .line-highlighted{color:#708090;padding-right:7px;border-right:1px solid #ffb44c;}:root[data-theme="ayu"] .search-results a:hover,:root[data-theme="ayu"] .search-results a:focus{color:#fff !important;background-color:#3c3c3c;}:root[data-theme="ayu"] .search-results a{color:#0096cf;}:root[data-theme="ayu"] .search-results a div.desc{color:#c5c5c5;}:root[data-theme="ayu"] .result-name .primitive>i,:root[data-theme="ayu"] .result-name .keyword>i{color:#788797;}:root[data-theme="ayu"] #search-tabs>button.selected{border-bottom:1px solid #ffb44c !important;border-top:none;}:root[data-theme="ayu"] #search-tabs>button:not(.selected){border:none;background-color:transparent !important;}:root[data-theme="ayu"] #search-tabs>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}:root[data-theme="ayu"] #settings-menu>a img{filter:invert(100);} \ No newline at end of file diff --git a/static.files/scrape-examples-ef1e698c1d417c0c.js b/static.files/scrape-examples-ef1e698c1d417c0c.js new file mode 100644 index 00000000..ba830e37 --- /dev/null +++ b/static.files/scrape-examples-ef1e698c1d417c0c.js @@ -0,0 +1 @@ +"use strict";(function(){const DEFAULT_MAX_LINES=5;const HIDDEN_MAX_LINES=10;function scrollToLoc(elt,loc,isHidden){const lines=elt.querySelector(".src-line-numbers");let scrollOffset;const maxLines=isHidden?HIDDEN_MAX_LINES:DEFAULT_MAX_LINES;if(loc[1]-loc[0]>maxLines){const line=Math.max(0,loc[0]-1);scrollOffset=lines.children[line].offsetTop}else{const wrapper=elt.querySelector(".code-wrapper");const halfHeight=wrapper.offsetHeight/2;const offsetTop=lines.children[loc[0]].offsetTop;const lastLine=lines.children[loc[1]];const offsetBot=lastLine.offsetTop+lastLine.offsetHeight;const offsetMid=(offsetTop+offsetBot)/2;scrollOffset=offsetMid-halfHeight}lines.scrollTo(0,scrollOffset);elt.querySelector(".rust").scrollTo(0,scrollOffset)}function updateScrapedExample(example,isHidden){const locs=JSON.parse(example.attributes.getNamedItem("data-locs").textContent);let locIndex=0;const highlights=Array.prototype.slice.call(example.querySelectorAll(".highlight"));const link=example.querySelector(".scraped-example-title a");if(locs.length>1){const onChangeLoc=changeIndex=>{removeClass(highlights[locIndex],"focus");changeIndex();scrollToLoc(example,locs[locIndex][0],isHidden);addClass(highlights[locIndex],"focus");const url=locs[locIndex][1];const title=locs[locIndex][2];link.href=url;link.innerHTML=title};example.querySelector(".prev").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex-1+locs.length)%locs.length})});example.querySelector(".next").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex+1)%locs.length})})}const expandButton=example.querySelector(".expand");if(expandButton){expandButton.addEventListener("click",()=>{if(hasClass(example,"expanded")){removeClass(example,"expanded");scrollToLoc(example,locs[0][0],isHidden)}else{addClass(example,"expanded")}})}scrollToLoc(example,locs[0][0],isHidden)}const firstExamples=document.querySelectorAll(".scraped-example-list > .scraped-example");onEachLazy(firstExamples,el=>updateScrapedExample(el,false));onEachLazy(document.querySelectorAll(".more-examples-toggle"),toggle=>{onEachLazy(toggle.querySelectorAll(".toggle-line, .hide-more"),button=>{button.addEventListener("click",()=>{toggle.open=false})});const moreExamples=toggle.querySelectorAll(".scraped-example");toggle.querySelector("summary").addEventListener("click",()=>{setTimeout(()=>{onEachLazy(moreExamples,el=>updateScrapedExample(el,true))})},{once:true})})})() \ No newline at end of file diff --git a/static.files/search-8fbf244ebcf71464.js b/static.files/search-8fbf244ebcf71464.js new file mode 100644 index 00000000..168023b4 --- /dev/null +++ b/static.files/search-8fbf244ebcf71464.js @@ -0,0 +1,5 @@ +"use strict";if(!Array.prototype.toSpliced){Array.prototype.toSpliced=function(){const me=this.slice();Array.prototype.splice.apply(me,arguments);return me}}(function(){const itemTypes=["mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","primitive","associatedtype","constant","associatedconstant","union","foreigntype","keyword","existential","attr","derive","traitalias","generic",];const longItemTypes=["module","extern crate","re-export","struct","enum","function","type alias","static","trait","","trait method","method","struct field","enum variant","macro","primitive type","assoc type","constant","assoc const","union","foreign type","keyword","existential type","attribute macro","derive macro","trait alias",];const TY_PRIMITIVE=itemTypes.indexOf("primitive");const TY_KEYWORD=itemTypes.indexOf("keyword");const TY_GENERIC=itemTypes.indexOf("generic");const ROOT_PATH=typeof window!=="undefined"?window.rootPath:"../";function hasOwnPropertyRustdoc(obj,property){return Object.prototype.hasOwnProperty.call(obj,property)}function printTab(nb){let iter=0;let foundCurrentTab=false;let foundCurrentResultSet=false;onEachLazy(document.getElementById("search-tabs").childNodes,elem=>{if(nb===iter){addClass(elem,"selected");foundCurrentTab=true}else{removeClass(elem,"selected")}iter+=1});const isTypeSearch=(nb>0||iter===1);iter=0;onEachLazy(document.getElementById("results").childNodes,elem=>{if(nb===iter){addClass(elem,"active");foundCurrentResultSet=true}else{removeClass(elem,"active")}iter+=1});if(foundCurrentTab&&foundCurrentResultSet){searchState.currentTab=nb;const correctionsElem=document.getElementsByClassName("search-corrections");if(isTypeSearch){removeClass(correctionsElem[0],"hidden")}else{addClass(correctionsElem[0],"hidden")}}else if(nb!==0){printTab(0)}}const editDistanceState={current:[],prev:[],prevPrev:[],calculate:function calculate(a,b,limit){if(a.lengthlimit){return limit+1}while(b.length>0&&b[0]===a[0]){a=a.substring(1);b=b.substring(1)}while(b.length>0&&b[b.length-1]===a[a.length-1]){a=a.substring(0,a.length-1);b=b.substring(0,b.length-1)}if(b.length===0){return minDist}const aLength=a.length;const bLength=b.length;for(let i=0;i<=bLength;++i){this.current[i]=0;this.prev[i]=i;this.prevPrev[i]=Number.MAX_VALUE}for(let i=1;i<=aLength;++i){this.current[0]=i;const aIdx=i-1;for(let j=1;j<=bLength;++j){const bIdx=j-1;const substitutionCost=a[aIdx]===b[bIdx]?0:1;this.current[j]=Math.min(this.prev[j]+1,this.current[j-1]+1,this.prev[j-1]+substitutionCost);if((i>1)&&(j>1)&&(a[aIdx]===b[bIdx-1])&&(a[aIdx-1]===b[bIdx])){this.current[j]=Math.min(this.current[j],this.prevPrev[j-2]+1)}}const prevPrevTmp=this.prevPrev;this.prevPrev=this.prev;this.prev=this.current;this.current=prevPrevTmp}const distance=this.prev[bLength];return distance<=limit?distance:(limit+1)},};function editDistance(a,b,limit){return editDistanceState.calculate(a,b,limit)}function initSearch(rawSearchIndex){const MAX_RESULTS=200;const NO_TYPE_FILTER=-1;let searchIndex;let currentResults;let typeNameIdMap;const ALIASES=new Map();let typeNameIdOfArray;let typeNameIdOfSlice;let typeNameIdOfArrayOrSlice;function buildTypeMapIndex(name){if(name===""||name===null){return null}if(typeNameIdMap.has(name)){return typeNameIdMap.get(name)}else{const id=typeNameIdMap.size;typeNameIdMap.set(name,id);return id}}function isWhitespace(c){return" \t\n\r".indexOf(c)!==-1}function isSpecialStartCharacter(c){return"<\"".indexOf(c)!==-1}function isEndCharacter(c){return",>-]".indexOf(c)!==-1}function isStopCharacter(c){return isEndCharacter(c)}function isErrorCharacter(c){return"()".indexOf(c)!==-1}function itemTypeFromName(typename){const index=itemTypes.findIndex(i=>i===typename);if(index<0){throw["Unknown type filter ",typename]}return index}function getStringElem(query,parserState,isInGenerics){if(isInGenerics){throw["Unexpected ","\""," in generics"]}else if(query.literalSearch){throw["Cannot have more than one literal search element"]}else if(parserState.totalElems-parserState.genericsElems>0){throw["Cannot use literal search when there is more than one element"]}parserState.pos+=1;const start=parserState.pos;const end=getIdentEndPosition(parserState);if(parserState.pos>=parserState.length){throw["Unclosed ","\""]}else if(parserState.userQuery[end]!=="\""){throw["Unexpected ",parserState.userQuery[end]," in a string element"]}else if(start===end){throw["Cannot have empty string element"]}parserState.pos+=1;query.literalSearch=true}function isPathStart(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="::"}function isReturnArrow(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="->"}function isIdentCharacter(c){return(c==="_"||(c>="0"&&c<="9")||(c>="a"&&c<="z")||(c>="A"&&c<="Z"))}function isSeparatorCharacter(c){return c===","}function isPathSeparator(c){return c===":"||isWhitespace(c)}function prevIs(parserState,lookingFor){let pos=parserState.pos;while(pos>0){const c=parserState.userQuery[pos-1];if(c===lookingFor){return true}else if(!isWhitespace(c)){break}pos-=1}return false}function isLastElemGeneric(elems,parserState){return(elems.length>0&&elems[elems.length-1].generics.length>0)||prevIs(parserState,">")}function skipWhitespace(parserState){while(parserState.pos0){throw["Cannot have more than one element if you use quotes"]}const typeFilter=parserState.typeFilter;parserState.typeFilter=null;if(name==="!"){if(typeFilter!==null&&typeFilter!=="primitive"){throw["Invalid search type: primitive never type ","!"," and ",typeFilter," both specified",]}if(generics.length!==0){throw["Never type ","!"," does not accept generic parameters",]}return{name:"never",id:null,fullPath:["never"],pathWithoutLast:[],pathLast:"never",generics:[],typeFilter:"primitive",}}if(path.startsWith("::")){throw["Paths cannot start with ","::"]}else if(path.endsWith("::")){throw["Paths cannot end with ","::"]}else if(path.includes("::::")){throw["Unexpected ","::::"]}else if(path.includes(" ::")){throw["Unexpected "," ::"]}else if(path.includes(":: ")){throw["Unexpected ",":: "]}const pathSegments=path.split(/::|\s+/);if(pathSegments.length===0||(pathSegments.length===1&&pathSegments[0]==="")){if(generics.length>0||prevIs(parserState,">")){throw["Found generics without a path"]}else{throw["Unexpected ",parserState.userQuery[parserState.pos]]}}for(const[i,pathSegment]of pathSegments.entries()){if(pathSegment==="!"){if(i!==0){throw["Never type ","!"," is not associated item"]}pathSegments[i]="never"}}parserState.totalElems+=1;if(isInGenerics){parserState.genericsElems+=1}return{name:name.trim(),id:null,fullPath:pathSegments,pathWithoutLast:pathSegments.slice(0,pathSegments.length-1),pathLast:pathSegments[pathSegments.length-1],generics:generics,typeFilter,}}function getIdentEndPosition(parserState){const start=parserState.pos;let end=parserState.pos;let foundExclamation=-1;while(parserState.pos=end){throw["Found generics without a path"]}parserState.pos+=1;getItemsBefore(query,parserState,generics,">")}if(isStringElem){skipWhitespace(parserState)}if(start>=end&&generics.length===0){return}elems.push(createQueryElement(query,parserState,parserState.userQuery.slice(start,end),generics,isInGenerics))}}function getItemsBefore(query,parserState,elems,endChar){let foundStopChar=true;let start=parserState.pos;const oldTypeFilter=parserState.typeFilter;parserState.typeFilter=null;let extra="";if(endChar===">"){extra="<"}else if(endChar==="]"){extra="["}else if(endChar===""){extra="->"}else{extra=endChar}while(parserState.pos"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(endChar!==""){throw["Expected ",","," or ",endChar,...extra,", found ",c,]}throw["Expected ",",",...extra,", found ",c,]}const posBefore=parserState.pos;start=parserState.pos;getNextElem(query,parserState,elems,endChar!=="");if(endChar!==""&&parserState.pos>=parserState.length){throw["Unclosed ",extra]}if(posBefore===parserState.pos){parserState.pos+=1}foundStopChar=false}if(parserState.pos>=parserState.length&&endChar!==""){throw["Unclosed ",extra]}parserState.pos+=1;parserState.typeFilter=oldTypeFilter}function checkExtraTypeFilterCharacters(start,parserState){const query=parserState.userQuery.slice(start,parserState.pos).trim();for(const c in query){if(!isIdentCharacter(query[c])){throw["Unexpected ",query[c]," in type filter (before ",":",")",]}}}function parseInput(query,parserState){let foundStopChar=true;let start=parserState.pos;while(parserState.pos"){if(isReturnArrow(parserState)){break}throw["Unexpected ",c," (did you mean ","->","?)"]}throw["Unexpected ",c]}else if(c===":"&&!isPathStart(parserState)){if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}else if(query.elems.length===0){throw["Expected type filter before ",":"]}else if(query.literalSearch){throw["Cannot use quotes on type filter"]}const typeFilterElem=query.elems.pop();checkExtraTypeFilterCharacters(start,parserState);parserState.typeFilter=typeFilterElem.name;parserState.pos+=1;parserState.totalElems-=1;query.literalSearch=false;foundStopChar=true;continue}else if(isWhitespace(c)){skipWhitespace(parserState);continue}if(!foundStopChar){let extra="";if(isLastElemGeneric(query.elems,parserState)){extra=[" after ",">"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(parserState.typeFilter!==null){throw["Expected ",","," or ","->",...extra,", found ",c,]}throw["Expected ",",",", ",":"," or ","->",...extra,", found ",c,]}const before=query.elems.length;start=parserState.pos;getNextElem(query,parserState,query.elems,false);if(query.elems.length===before){parserState.pos+=1}foundStopChar=false}if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}while(parserState.pos"]}break}else{parserState.pos+=1}}}function newParsedQuery(userQuery){return{original:userQuery,userQuery:userQuery.toLowerCase(),elems:[],returned:[],foundElems:0,totalElems:0,literalSearch:false,error:null,correction:null,proposeCorrectionFrom:null,proposeCorrectionTo:null,}}function buildUrl(search,filterCrates){let extra="?search="+encodeURIComponent(search);if(filterCrates!==null){extra+="&filter-crate="+encodeURIComponent(filterCrates)}return getNakedUrl()+extra+window.location.hash}function getFilterCrates(){const elem=document.getElementById("crate-search");if(elem&&elem.value!=="all crates"&&hasOwnPropertyRustdoc(rawSearchIndex,elem.value)){return elem.value}return null}function parseQuery(userQuery){function convertTypeFilterOnElem(elem){if(elem.typeFilter!==null){let typeFilter=elem.typeFilter;if(typeFilter==="const"){typeFilter="constant"}elem.typeFilter=itemTypeFromName(typeFilter)}else{elem.typeFilter=NO_TYPE_FILTER}for(const elem2 of elem.generics){convertTypeFilterOnElem(elem2)}}userQuery=userQuery.trim();const parserState={length:userQuery.length,pos:0,totalElems:0,genericsElems:0,typeFilter:null,userQuery:userQuery.toLowerCase(),};let query=newParsedQuery(userQuery);try{parseInput(query,parserState);for(const elem of query.elems){convertTypeFilterOnElem(elem)}for(const elem of query.returned){convertTypeFilterOnElem(elem)}}catch(err){query=newParsedQuery(userQuery);query.error=err;return query}if(!query.literalSearch){query.literalSearch=parserState.totalElems>1}query.foundElems=query.elems.length+query.returned.length;query.totalElems=parserState.totalElems;return query}function createQueryResults(results_in_args,results_returned,results_others,parsedQuery){return{"in_args":results_in_args,"returned":results_returned,"others":results_others,"query":parsedQuery,}}function execQuery(parsedQuery,searchWords,filterCrates,currentCrate){const results_others=new Map(),results_in_args=new Map(),results_returned=new Map();function transformResults(results){const duplicates=new Set();const out=[];for(const result of results){if(result.id!==-1){const obj=searchIndex[result.id];obj.dist=result.dist;const res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=obj.displayPath+obj.name;obj.fullPath+="|"+obj.ty;if(duplicates.has(obj.fullPath)){continue}duplicates.add(obj.fullPath);obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}return out}function sortResults(results,isType,preferredCrate){if(results.size===0){return[]}const userQuery=parsedQuery.userQuery;const result_list=[];for(const result of results.values()){result.word=searchWords[result.id];result.item=searchIndex[result.id]||{};result_list.push(result)}result_list.sort((aaa,bbb)=>{let a,b;a=(aaa.word!==userQuery);b=(bbb.word!==userQuery);if(a!==b){return a-b}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.path_dist;b=bbb.path_dist;if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}a=(aaa.dist);b=(bbb.dist);if(a!==b){return a-b}a=aaa.item.deprecated;b=bbb.item.deprecated;if(a!==b){return a-b}a=(aaa.item.crate!==preferredCrate);b=(bbb.item.crate!==preferredCrate);if(a!==b){return a-b}a=aaa.word.length;b=bbb.word.length;if(a!==b){return a-b}a=aaa.word;b=bbb.word;if(a!==b){return(a>b?+1:-1)}if((aaa.item.ty===TY_PRIMITIVE&&bbb.item.ty!==TY_KEYWORD)||(aaa.item.ty===TY_KEYWORD&&bbb.item.ty!==TY_PRIMITIVE)){return-1}if((bbb.item.ty===TY_PRIMITIVE&&aaa.item.ty!==TY_PRIMITIVE)||(bbb.item.ty===TY_KEYWORD&&aaa.item.ty!==TY_KEYWORD)){return 1}a=(aaa.item.desc==="");b=(bbb.item.desc==="");if(a!==b){return a-b}a=aaa.item.ty;b=bbb.item.ty;if(a!==b){return a-b}a=aaa.item.path;b=bbb.item.path;if(a!==b){return(a>b?+1:-1)}return 0});let nameSplit=null;if(parsedQuery.elems.length===1){const hasPath=typeof parsedQuery.elems[0].path==="undefined";nameSplit=hasPath?null:parsedQuery.elems[0].path}for(const result of result_list){if(result.dontValidate){continue}const name=result.item.name.toLowerCase(),path=result.item.path.toLowerCase(),parent=result.item.parent;if(!isType&&!validateResult(name,path,nameSplit,parent)){result.id=-1}}return transformResults(result_list)}function checkGenerics(fnType,queryElem,whereClause,mgensInout){return unifyFunctionTypes(fnType.generics,queryElem.generics,whereClause,mgensInout,mgens=>{if(mgensInout){for(const[fid,qid]of mgens.entries()){mgensInout.set(fid,qid)}}return true})}function unifyFunctionTypes(fnTypesIn,queryElems,whereClause,mgensIn,solutionCb){let mgens=new Map(mgensIn);if(queryElems.length===0){return!solutionCb||solutionCb(mgens)}if(!fnTypesIn||fnTypesIn.length===0){return false}const ql=queryElems.length;let fl=fnTypesIn.length;let fnTypes=fnTypesIn.slice();const backtracking=[];let i=0;let j=0;const backtrack=()=>{while(backtracking.length!==0){const{fnTypesScratch,mgensScratch,queryElemsOffset,fnTypesOffset,unbox,}=backtracking.pop();mgens=new Map(mgensScratch);const fnType=fnTypesScratch[fnTypesOffset];const queryElem=queryElems[queryElemsOffset];if(unbox){if(fnType.id<0){if(mgens.has(fnType.id)&&mgens.get(fnType.id)!==0){continue}mgens.set(fnType.id,0)}const generics=fnType.id<0?whereClause[(-fnType.id)-1]:fnType.generics;fnTypes=fnTypesScratch.toSpliced(fnTypesOffset,1,...generics);fl=fnTypes.length;i=queryElemsOffset-1}else{if(fnType.id<0){if(mgens.has(fnType.id)&&mgens.get(fnType.id)!==queryElem.id){continue}mgens.set(fnType.id,queryElem.id)}fnTypes=fnTypesScratch.slice();fl=fnTypes.length;const tmp=fnTypes[queryElemsOffset];fnTypes[queryElemsOffset]=fnTypes[fnTypesOffset];fnTypes[fnTypesOffset]=tmp;i=queryElemsOffset}return true}return false};for(i=0;i!==ql;++i){const queryElem=queryElems[i];const matchCandidates=[];let fnTypesScratch=null;let mgensScratch=null;for(j=i;j!==fl;++j){const fnType=fnTypes[j];if(unifyFunctionTypeIsMatchCandidate(fnType,queryElem,whereClause,mgens)){if(!fnTypesScratch){fnTypesScratch=fnTypes.slice()}unifyFunctionTypes(fnType.generics,queryElem.generics,whereClause,mgens,mgensScratch=>{matchCandidates.push({fnTypesScratch,mgensScratch,queryElemsOffset:i,fnTypesOffset:j,unbox:false,});return false})}if(unifyFunctionTypeIsUnboxCandidate(fnType,queryElem,whereClause,mgens)){if(!fnTypesScratch){fnTypesScratch=fnTypes.slice()}if(!mgensScratch){mgensScratch=new Map(mgens)}backtracking.push({fnTypesScratch,mgensScratch,queryElemsOffset:i,fnTypesOffset:j,unbox:true,})}}if(matchCandidates.length===0){if(backtrack()){continue}else{return false}}const{fnTypesOffset:candidate,mgensScratch:mgensNew}=matchCandidates.pop();if(fnTypes[candidate].id<0&&queryElems[i].id<0){mgens.set(fnTypes[candidate].id,queryElems[i].id)}for(const[fid,qid]of mgensNew){mgens.set(fid,qid)}const tmp=fnTypes[candidate];fnTypes[candidate]=fnTypes[i];fnTypes[i]=tmp;for(const otherCandidate of matchCandidates){backtracking.push(otherCandidate)}while(i===(ql-1)&&solutionCb&&!solutionCb(mgens)){if(!backtrack()){return false}}}return true}function unifyFunctionTypeIsMatchCandidate(fnType,queryElem,whereClause,mgens){if(!typePassesFilter(queryElem.typeFilter,fnType.ty)){return false}if(fnType.id<0&&queryElem.id<0){if(mgens.has(fnType.id)&&mgens.get(fnType.id)!==queryElem.id){return false}for(const[fid,qid]of mgens.entries()){if(fnType.id!==fid&&queryElem.id===qid){return false}if(fnType.id===fid&&queryElem.id!==qid){return false}}}else{if(queryElem.id===typeNameIdOfArrayOrSlice&&(fnType.id===typeNameIdOfSlice||fnType.id===typeNameIdOfArray)){}else if(fnType.id!==queryElem.id){return false}if(fnType.generics.length===0&&queryElem.generics.length!==0){return false}const queryElemPathLength=queryElem.pathWithoutLast.length;if(queryElemPathLength>0){const fnTypePath=fnType.path!==undefined&&fnType.path!==null?fnType.path.split("::"):[];if(queryElemPathLength>fnTypePath.length){return false}let i=0;for(const path of fnTypePath){if(path===queryElem.pathWithoutLast[i]){i+=1;if(i>=queryElemPathLength){break}}}if(i=0){if(!whereClause){return false}if(mgens.has(fnType.id)&&mgens.get(fnType.id)!==0){return false}return checkIfInList(whereClause[(-fnType.id)-1],queryElem,whereClause)}else if(fnType.generics&&fnType.generics.length>0){return checkIfInList(fnType.generics,queryElem,whereClause)}return false}function checkIfInList(list,elem,whereClause){for(const entry of list){if(checkType(entry,elem,whereClause)){return true}}return false}function checkType(row,elem,whereClause){if(row.id===null){return row.generics.length>0?checkIfInList(row.generics,elem,whereClause):false}if(row.id<0&&elem.id>=0){const gid=(-row.id)-1;return checkIfInList(whereClause[gid],elem,whereClause)}if(row.id<0&&elem.id<0){return true}const matchesExact=row.id===elem.id;const matchesArrayOrSlice=elem.id===typeNameIdOfArrayOrSlice&&(row.id===typeNameIdOfSlice||row.id===typeNameIdOfArray);if((matchesExact||matchesArrayOrSlice)&&typePassesFilter(elem.typeFilter,row.ty)){if(elem.generics.length>0){return checkGenerics(row,elem,whereClause,new Map())}return true}return checkIfInList(row.generics,elem,whereClause)}function checkPath(contains,ty,maxEditDistance){if(contains.length===0){return 0}let ret_dist=maxEditDistance+1;const path=ty.path.split("::");if(ty.parent&&ty.parent.name){path.push(ty.parent.name.toLowerCase())}const length=path.length;const clength=contains.length;if(clength>length){return maxEditDistance+1}for(let i=0;ilength){break}let dist_total=0;let aborted=false;for(let x=0;xmaxEditDistance){aborted=true;break}dist_total+=dist}if(!aborted){ret_dist=Math.min(ret_dist,Math.round(dist_total/clength))}}return ret_dist}function typePassesFilter(filter,type){if(filter<=NO_TYPE_FILTER||filter===type)return true;const name=itemTypes[type];switch(itemTypes[filter]){case"constant":return name==="associatedconstant";case"fn":return name==="method"||name==="tymethod";case"type":return name==="primitive"||name==="associatedtype";case"trait":return name==="traitalias"}return false}function createAliasFromItem(item){return{crate:item.crate,name:item.name,path:item.path,desc:item.desc,ty:item.ty,parent:item.parent,type:item.type,is_alias:true,deprecated:item.deprecated,implDisambiguator:item.implDisambiguator,}}function handleAliases(ret,query,filterCrates,currentCrate){const lowerQuery=query.toLowerCase();const aliases=[];const crateAliases=[];if(filterCrates!==null){if(ALIASES.has(filterCrates)&&ALIASES.get(filterCrates).has(lowerQuery)){const query_aliases=ALIASES.get(filterCrates).get(lowerQuery);for(const alias of query_aliases){aliases.push(createAliasFromItem(searchIndex[alias]))}}}else{for(const[crate,crateAliasesIndex]of ALIASES){if(crateAliasesIndex.has(lowerQuery)){const pushTo=crate===currentCrate?crateAliases:aliases;const query_aliases=crateAliasesIndex.get(lowerQuery);for(const alias of query_aliases){pushTo.push(createAliasFromItem(searchIndex[alias]))}}}}const sortFunc=(aaa,bbb)=>{if(aaa.path{alias.alias=query;const res=buildHrefAndPath(alias);alias.displayPath=pathSplitter(res[0]);alias.fullPath=alias.displayPath+alias.name;alias.href=res[1];ret.others.unshift(alias);if(ret.others.length>MAX_RESULTS){ret.others.pop()}};aliases.forEach(pushFunc);crateAliases.forEach(pushFunc)}function addIntoResults(results,fullId,id,index,dist,path_dist,maxEditDistance){const inBounds=dist<=maxEditDistance||index!==-1;if(dist===0||(!parsedQuery.literalSearch&&inBounds)){if(results.has(fullId)){const result=results.get(fullId);if(result.dontValidate||result.dist<=dist){return}}results.set(fullId,{id:id,index:index,dontValidate:parsedQuery.literalSearch,dist:dist,path_dist:path_dist,})}}function handleSingleArg(row,pos,elem,results_others,results_in_args,results_returned,maxEditDistance){if(!row||(filterCrates!==null&&row.crate!==filterCrates)){return}let index=-1,path_dist=0;const fullId=row.id;const searchWord=searchWords[pos];const in_args=row.type&&row.type.inputs&&checkIfInList(row.type.inputs,elem,row.type.where_clause);if(in_args){addIntoResults(results_in_args,fullId,pos,-1,0,0,maxEditDistance)}const returned=row.type&&row.type.output&&checkIfInList(row.type.output,elem,row.type.where_clause);if(returned){addIntoResults(results_returned,fullId,pos,-1,0,0,maxEditDistance)}if(!typePassesFilter(elem.typeFilter,row.ty)){return}const row_index=row.normalizedName.indexOf(elem.pathLast);const word_index=searchWord.indexOf(elem.pathLast);if(row_index===-1){index=word_index}else if(word_index===-1){index=row_index}else if(word_index1){path_dist=checkPath(elem.pathWithoutLast,row,maxEditDistance);if(path_dist>maxEditDistance){return}}if(parsedQuery.literalSearch){if(searchWord===elem.name){addIntoResults(results_others,fullId,pos,index,0,path_dist)}return}const dist=editDistance(searchWord,elem.pathLast,maxEditDistance);if(index===-1&&dist+path_dist>maxEditDistance){return}addIntoResults(results_others,fullId,pos,index,dist,path_dist,maxEditDistance)}function handleArgs(row,pos,results){if(!row||(filterCrates!==null&&row.crate!==filterCrates)||!row.type){return}if(!unifyFunctionTypes(row.type.inputs,parsedQuery.elems,row.type.where_clause,null,mgens=>{return unifyFunctionTypes(row.type.output,parsedQuery.returned,row.type.where_clause,mgens)})){return}addIntoResults(results,row.id,pos,0,0,0,Number.MAX_VALUE)}function innerRunQuery(){let elem,i,nSearchWords,in_returned,row;let queryLen=0;for(const elem of parsedQuery.elems){queryLen+=elem.name.length}for(const elem of parsedQuery.returned){queryLen+=elem.name.length}const maxEditDistance=Math.floor(queryLen/3);const genericSymbols=new Map();function convertNameToId(elem){if(typeNameIdMap.has(elem.pathLast)){elem.id=typeNameIdMap.get(elem.pathLast)}else if(!parsedQuery.literalSearch){let match=null;let matchDist=maxEditDistance+1;let matchName="";for(const[name,id]of typeNameIdMap){const dist=editDistance(name,elem.pathLast,maxEditDistance);if(dist<=matchDist&&dist<=maxEditDistance){if(dist===matchDist&&matchName>name){continue}match=id;matchDist=dist;matchName=name}}if(match!==null){parsedQuery.correction=matchName}elem.id=match}if((elem.id===null&&parsedQuery.totalElems>1&&elem.typeFilter===-1&&elem.generics.length===0)||elem.typeFilter===TY_GENERIC){if(genericSymbols.has(elem.name)){elem.id=genericSymbols.get(elem.name)}else{elem.id=-(genericSymbols.size+1);genericSymbols.set(elem.name,elem.id)}if(elem.typeFilter===-1&&elem.name.length>=3){const maxPartDistance=Math.floor(elem.name.length/3);let matchDist=maxPartDistance+1;let matchName="";for(const name of typeNameIdMap.keys()){const dist=editDistance(name,elem.name,maxPartDistance);if(dist<=matchDist&&dist<=maxPartDistance){if(dist===matchDist&&matchName>name){continue}matchDist=dist;matchName=name}}if(matchName!==""){parsedQuery.proposeCorrectionFrom=elem.name;parsedQuery.proposeCorrectionTo=matchName}}elem.typeFilter=TY_GENERIC}if(elem.generics.length>0&&elem.typeFilter===TY_GENERIC){parsedQuery.error=["Generic type parameter ",elem.name," does not accept generic parameters",]}for(const elem2 of elem.generics){convertNameToId(elem2)}}for(const elem of parsedQuery.elems){convertNameToId(elem)}for(const elem of parsedQuery.returned){convertNameToId(elem)}if(parsedQuery.foundElems===1){if(parsedQuery.elems.length===1){elem=parsedQuery.elems[0];for(i=0,nSearchWords=searchWords.length;i0){for(i=0,nSearchWords=searchWords.length;i-1||path.indexOf(key)>-1||(parent!==undefined&&parent.name!==undefined&&parent.name.toLowerCase().indexOf(key)>-1)||editDistance(name,key,maxEditDistance)<=maxEditDistance)){return false}}return true}function nextTab(direction){const next=(searchState.currentTab+direction+3)%searchState.focusedByTab.length;searchState.focusedByTab[searchState.currentTab]=document.activeElement;printTab(next);focusSearchResult()}function focusSearchResult(){const target=searchState.focusedByTab[searchState.currentTab]||document.querySelectorAll(".search-results.active a").item(0)||document.querySelectorAll("#search-tabs button").item(searchState.currentTab);searchState.focusedByTab[searchState.currentTab]=null;if(target){target.focus()}}function buildHrefAndPath(item){let displayPath;let href;const type=itemTypes[item.ty];const name=item.name;let path=item.path;if(type==="mod"){displayPath=path+"::";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+name+"/index.html"}else if(type==="import"){displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/index.html#reexport."+name}else if(type==="primitive"||type==="keyword"){displayPath="";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+type+"."+name+".html"}else if(type==="externcrate"){displayPath="";href=ROOT_PATH+name+"/index.html"}else if(item.parent!==undefined){const myparent=item.parent;let anchor=type+"."+name;const parentType=itemTypes[myparent.ty];let pageType=parentType;let pageName=myparent.name;if(parentType==="primitive"){displayPath=myparent.name+"::"}else if(type==="structfield"&&parentType==="variant"){const enumNameIdx=item.path.lastIndexOf("::");const enumName=item.path.substr(enumNameIdx+2);path=item.path.substr(0,enumNameIdx);displayPath=path+"::"+enumName+"::"+myparent.name+"::";anchor="variant."+myparent.name+".field."+name;pageType="enum";pageName=enumName}else{displayPath=path+"::"+myparent.name+"::"}if(item.implDisambiguator!==null){anchor=item.implDisambiguator+"/"+anchor}href=ROOT_PATH+path.replace(/::/g,"/")+"/"+pageType+"."+pageName+".html#"+anchor}else{displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html"}return[displayPath,href]}function pathSplitter(path){const tmp=""+path.replace(/::/g,"::");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}function addTab(array,query,display){let extraClass="";if(display===true){extraClass=" active"}const output=document.createElement("div");let length=0;if(array.length>0){output.className="search-results "+extraClass;array.forEach(item=>{const name=item.name;const type=itemTypes[item.ty];const longType=longItemTypes[item.ty];const typeName=longType.length!==0?`${longType}`:"?";length+=1;const link=document.createElement("a");link.className="result-"+type;link.href=item.href;const resultName=document.createElement("div");resultName.className="result-name";resultName.insertAdjacentHTML("beforeend",`${typeName}`);link.appendChild(resultName);let alias=" ";if(item.is_alias){alias=`
\ +${item.alias} - see \ +
`}resultName.insertAdjacentHTML("beforeend",`
${alias}\ +${item.displayPath}${name}\ +
`);const description=document.createElement("div");description.className="desc";description.insertAdjacentHTML("beforeend",item.desc);link.appendChild(description);output.appendChild(link)})}else if(query.error===null){output.className="search-failed"+extraClass;output.innerHTML="No results :(
"+"Try on DuckDuckGo?

"+"Or try looking in one of these:"}return[output,length]}function makeTabHeader(tabNb,text,nbElems){const fmtNbElems=nbElems<10?`\u{2007}(${nbElems})\u{2007}\u{2007}`:nbElems<100?`\u{2007}(${nbElems})\u{2007}`:`\u{2007}(${nbElems})`;if(searchState.currentTab===tabNb){return""}return""}function showResults(results,go_to_first,filterCrates){const search=searchState.outputElement();if(go_to_first||(results.others.length===1&&getSettingValue("go-to-only-result")==="true")){window.onunload=()=>{};searchState.removeQueryParameters();const elem=document.createElement("a");elem.href=results.others[0].href;removeClass(elem,"active");document.body.appendChild(elem);elem.click();return}if(results.query===undefined){results.query=parseQuery(searchState.input.value)}currentResults=results.query.userQuery;const ret_others=addTab(results.others,results.query,true);const ret_in_args=addTab(results.in_args,results.query,false);const ret_returned=addTab(results.returned,results.query,false);let currentTab=searchState.currentTab;if((currentTab===0&&ret_others[1]===0)||(currentTab===1&&ret_in_args[1]===0)||(currentTab===2&&ret_returned[1]===0)){if(ret_others[1]!==0){currentTab=0}else if(ret_in_args[1]!==0){currentTab=1}else if(ret_returned[1]!==0){currentTab=2}}let crates="";const crates_list=Object.keys(rawSearchIndex);if(crates_list.length>1){crates=" in 
"}let output=`

Results${crates}

`;if(results.query.error!==null){const error=results.query.error;error.forEach((value,index)=>{value=value.split("<").join("<").split(">").join(">");if(index%2!==0){error[index]=`${value.replaceAll(" ", " ")}`}else{error[index]=value}});output+=`

Query parser error: "${error.join("")}".

`;output+="
"+makeTabHeader(0,"In Names",ret_others[1])+"
";currentTab=0}else if(results.query.foundElems<=1&&results.query.returned.length===0){output+="
"+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+"
"}else{const signatureTabTitle=results.query.elems.length===0?"In Function Return Types":results.query.returned.length===0?"In Function Parameters":"In Function Signatures";output+="
"+makeTabHeader(0,signatureTabTitle,ret_others[1])+"
";currentTab=0}if(results.query.correction!==null){const orig=results.query.returned.length>0?results.query.returned[0].name:results.query.elems[0].name;output+="

"+`Type "${orig}" not found. `+"Showing results for closest type name "+`"${results.query.correction}" instead.

`}if(results.query.proposeCorrectionFrom!==null){const orig=results.query.proposeCorrectionFrom;const targ=results.query.proposeCorrectionTo;output+="

"+`Type "${orig}" not found and used as generic parameter. `+`Consider searching for "${targ}" instead.

`}const resultsElem=document.createElement("div");resultsElem.id="results";resultsElem.appendChild(ret_others[0]);resultsElem.appendChild(ret_in_args[0]);resultsElem.appendChild(ret_returned[0]);search.innerHTML=output;const crateSearch=document.getElementById("crate-search");if(crateSearch){crateSearch.addEventListener("input",updateCrate)}search.appendChild(resultsElem);searchState.showResults(search);const elems=document.getElementById("search-tabs").childNodes;searchState.focusedByTab=[];let i=0;for(const elem of elems){const j=i;elem.onclick=()=>printTab(j);searchState.focusedByTab.push(null);i+=1}printTab(currentTab)}function updateSearchHistory(url){if(!browserSupportsHistoryApi()){return}const params=searchState.getQueryStringParams();if(!history.state&&!params.search){history.pushState(null,"",url)}else{history.replaceState(null,"",url)}}function search(e,forced){if(e){e.preventDefault()}const query=parseQuery(searchState.input.value.trim());let filterCrates=getFilterCrates();if(!forced&&query.userQuery===currentResults){if(query.userQuery.length>0){putBackSearch()}return}searchState.setLoadingSearch();const params=searchState.getQueryStringParams();if(filterCrates===null&¶ms["filter-crate"]!==undefined){filterCrates=params["filter-crate"]}searchState.title="Results for "+query.original+" - Rust";updateSearchHistory(buildUrl(query.original,filterCrates));showResults(execQuery(query,searchWords,filterCrates,window.currentCrate),params.go_to_first,filterCrates)}function buildItemSearchTypeAll(types,lowercasePaths){return types.map(type=>buildItemSearchType(type,lowercasePaths))}function buildItemSearchType(type,lowercasePaths){const PATH_INDEX_DATA=0;const GENERICS_DATA=1;let pathIndex,generics;if(typeof type==="number"){pathIndex=type;generics=[]}else{pathIndex=type[PATH_INDEX_DATA];generics=buildItemSearchTypeAll(type[GENERICS_DATA],lowercasePaths)}if(pathIndex<0){return{id:pathIndex,ty:TY_GENERIC,path:null,generics,}}if(pathIndex===0){return{id:null,ty:null,path:null,generics,}}const item=lowercasePaths[pathIndex-1];return{id:buildTypeMapIndex(item.name),ty:item.ty,path:item.path,generics,}}function buildFunctionSearchType(functionSearchType,lowercasePaths){const INPUTS_DATA=0;const OUTPUT_DATA=1;if(functionSearchType===0){return null}let inputs,output;if(typeof functionSearchType[INPUTS_DATA]==="number"){inputs=[buildItemSearchType(functionSearchType[INPUTS_DATA],lowercasePaths)]}else{inputs=buildItemSearchTypeAll(functionSearchType[INPUTS_DATA],lowercasePaths)}if(functionSearchType.length>1){if(typeof functionSearchType[OUTPUT_DATA]==="number"){output=[buildItemSearchType(functionSearchType[OUTPUT_DATA],lowercasePaths)]}else{output=buildItemSearchTypeAll(functionSearchType[OUTPUT_DATA],lowercasePaths)}}else{output=[]}const where_clause=[];const l=functionSearchType.length;for(let i=2;i2){path=itemPaths.has(elem[2])?itemPaths.get(elem[2]):lastPath;lastPath=path}lowercasePaths.push({ty:ty,name:name.toLowerCase(),path:path});paths[i]={ty:ty,name:name,path:path}}lastPath="";len=itemTypes.length;for(let i=0;i0?paths[itemParentIdxs[i]-1]:undefined,type:buildFunctionSearchType(itemFunctionSearchTypes[i],lowercasePaths),id:id,normalizedName:word.indexOf("_")===-1?word:word.replace(/_/g,""),deprecated:deprecatedItems.has(i),implDisambiguator:implDisambiguator.has(i)?implDisambiguator.get(i):null,};id+=1;searchIndex.push(row);lastPath=row.path;crateSize+=1}if(aliases){const currentCrateAliases=new Map();ALIASES.set(crate,currentCrateAliases);for(const alias_name in aliases){if(!hasOwnPropertyRustdoc(aliases,alias_name)){continue}let currentNameAliases;if(currentCrateAliases.has(alias_name)){currentNameAliases=currentCrateAliases.get(alias_name)}else{currentNameAliases=[];currentCrateAliases.set(alias_name,currentNameAliases)}for(const local_alias of aliases[alias_name]){currentNameAliases.push(local_alias+currentIndex)}}}currentIndex+=crateSize}return searchWords}function onSearchSubmit(e){e.preventDefault();searchState.clearInputTimeout();search()}function putBackSearch(){const search_input=searchState.input;if(!searchState.input){return}if(search_input.value!==""&&!searchState.isDisplayed()){searchState.showResults();if(browserSupportsHistoryApi()){history.replaceState(null,"",buildUrl(search_input.value,getFilterCrates()))}document.title=searchState.title}}function registerSearchEvents(){const params=searchState.getQueryStringParams();if(searchState.input.value===""){searchState.input.value=params.search||""}const searchAfter500ms=()=>{searchState.clearInputTimeout();if(searchState.input.value.length===0){searchState.hideResults()}else{searchState.timeout=setTimeout(search,500)}};searchState.input.onkeyup=searchAfter500ms;searchState.input.oninput=searchAfter500ms;document.getElementsByClassName("search-form")[0].onsubmit=onSearchSubmit;searchState.input.onchange=e=>{if(e.target!==document.activeElement){return}searchState.clearInputTimeout();setTimeout(search,0)};searchState.input.onpaste=searchState.input.onchange;searchState.outputElement().addEventListener("keydown",e=>{if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey){return}if(e.which===38){const previous=document.activeElement.previousElementSibling;if(previous){previous.focus()}else{searchState.focus()}e.preventDefault()}else if(e.which===40){const next=document.activeElement.nextElementSibling;if(next){next.focus()}const rect=document.activeElement.getBoundingClientRect();if(window.innerHeight-rect.bottom{if(e.which===40){focusSearchResult();e.preventDefault()}});searchState.input.addEventListener("focus",()=>{putBackSearch()});searchState.input.addEventListener("blur",()=>{searchState.input.placeholder=searchState.input.origPlaceholder});if(browserSupportsHistoryApi()){const previousTitle=document.title;window.addEventListener("popstate",e=>{const params=searchState.getQueryStringParams();document.title=previousTitle;currentResults=null;if(params.search&¶ms.search.length>0){searchState.input.value=params.search;search(e)}else{searchState.input.value="";searchState.hideResults()}})}window.onpageshow=()=>{const qSearch=searchState.getQueryStringParams().search;if(searchState.input.value===""&&qSearch){searchState.input.value=qSearch}search()}}function updateCrate(ev){if(ev.target.value==="all crates"){const query=searchState.input.value.trim();updateSearchHistory(buildUrl(query,null))}currentResults=null;search(undefined,true)}const searchWords=buildIndex(rawSearchIndex);if(typeof window!=="undefined"){registerSearchEvents();if(window.searchState.getQueryStringParams().search){search()}}if(typeof exports!=="undefined"){exports.initSearch=initSearch;exports.execQuery=execQuery;exports.parseQuery=parseQuery}return searchWords}if(typeof window!=="undefined"){window.initSearch=initSearch;if(window.searchIndex!==undefined){initSearch(window.searchIndex)}}else{initSearch({})}})() \ No newline at end of file diff --git a/static.files/settings-74424d7eec62a23e.js b/static.files/settings-74424d7eec62a23e.js new file mode 100644 index 00000000..3014f75c --- /dev/null +++ b/static.files/settings-74424d7eec62a23e.js @@ -0,0 +1,17 @@ +"use strict";(function(){const isSettingsPage=window.location.pathname.endsWith("/settings.html");function changeSetting(settingName,value){if(settingName==="theme"){const useSystem=value==="system preference"?"true":"false";updateLocalStorage("use-system-theme",useSystem)}updateLocalStorage(settingName,value);switch(settingName){case"theme":case"preferred-dark-theme":case"preferred-light-theme":updateTheme();updateLightAndDark();break;case"line-numbers":if(value===true){window.rustdoc_add_line_numbers_to_examples()}else{window.rustdoc_remove_line_numbers_from_examples()}break}}function showLightAndDark(){removeClass(document.getElementById("preferred-light-theme"),"hidden");removeClass(document.getElementById("preferred-dark-theme"),"hidden")}function hideLightAndDark(){addClass(document.getElementById("preferred-light-theme"),"hidden");addClass(document.getElementById("preferred-dark-theme"),"hidden")}function updateLightAndDark(){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||(useSystem===null&&getSettingValue("theme")===null)){showLightAndDark()}else{hideLightAndDark()}}function setEvents(settingsElement){updateLightAndDark();onEachLazy(settingsElement.querySelectorAll("input[type=\"checkbox\"]"),toggle=>{const settingId=toggle.id;const settingValue=getSettingValue(settingId);if(settingValue!==null){toggle.checked=settingValue==="true"}toggle.onchange=()=>{changeSetting(toggle.id,toggle.checked)}});onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"),elem=>{const settingId=elem.name;let settingValue=getSettingValue(settingId);if(settingId==="theme"){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||settingValue===null){settingValue=useSystem==="false"?"light":"system preference"}}if(settingValue!==null&&settingValue!=="null"){elem.checked=settingValue===elem.value}elem.addEventListener("change",ev=>{changeSetting(ev.target.name,ev.target.value)})})}function buildSettingsPageSections(settings){let output="";for(const setting of settings){const js_data_name=setting["js_name"];const setting_name=setting["name"];if(setting["options"]!==undefined){output+=`\ +
+
${setting_name}
+
`;onEach(setting["options"],option=>{const checked=option===setting["default"]?" checked":"";const full=`${js_data_name}-${option.replace(/ /g,"-")}`;output+=`\ + `});output+=`\ +
+
`}else{const checked=setting["default"]===true?" checked":"";output+=`\ +
\ + \ +
`}}return output}function buildSettingsPage(){const theme_names=getVar("themes").split(",").filter(t=>t);theme_names.push("light","dark","ayu");const settings=[{"name":"Theme","js_name":"theme","default":"system preference","options":theme_names.concat("system preference"),},{"name":"Preferred light theme","js_name":"preferred-light-theme","default":"light","options":theme_names,},{"name":"Preferred dark theme","js_name":"preferred-dark-theme","default":"dark","options":theme_names,},{"name":"Auto-hide item contents for large items","js_name":"auto-hide-large-items","default":true,},{"name":"Auto-hide item methods' documentation","js_name":"auto-hide-method-docs","default":false,},{"name":"Auto-hide trait implementation documentation","js_name":"auto-hide-trait-implementations","default":false,},{"name":"Directly go to item in search if there is only one result","js_name":"go-to-only-result","default":false,},{"name":"Show line numbers on code examples","js_name":"line-numbers","default":false,},{"name":"Disable keyboard shortcuts","js_name":"disable-shortcuts","default":false,},];const elementKind=isSettingsPage?"section":"div";const innerHTML=`
${buildSettingsPageSections(settings)}
`;const el=document.createElement(elementKind);el.id="settings";if(!isSettingsPage){el.className="popover"}el.innerHTML=innerHTML;if(isSettingsPage){document.getElementById(MAIN_ID).appendChild(el)}else{el.setAttribute("tabindex","-1");getSettingsButton().appendChild(el)}return el}const settingsMenu=buildSettingsPage();function displaySettings(){settingsMenu.style.display=""}function settingsBlurHandler(event){blurHandler(event,getSettingsButton(),window.hidePopoverMenus)}if(isSettingsPage){getSettingsButton().onclick=event=>{event.preventDefault()}}else{const settingsButton=getSettingsButton();const settingsMenu=document.getElementById("settings");settingsButton.onclick=event=>{if(elemIsInParent(event.target,settingsMenu)){return}event.preventDefault();const shouldDisplaySettings=settingsMenu.style.display==="none";window.hideAllModals();if(shouldDisplaySettings){displaySettings()}};settingsButton.onblur=settingsBlurHandler;settingsButton.querySelector("a").onblur=settingsBlurHandler;onEachLazy(settingsMenu.querySelectorAll("input"),el=>{el.onblur=settingsBlurHandler});settingsMenu.onblur=settingsBlurHandler}setTimeout(()=>{setEvents(settingsMenu);if(!isSettingsPage){displaySettings()}removeClass(getSettingsButton(),"rotate")},0)})() \ No newline at end of file diff --git a/static.files/src-script-3280b574d94e47b4.js b/static.files/src-script-3280b574d94e47b4.js new file mode 100644 index 00000000..9ea88921 --- /dev/null +++ b/static.files/src-script-3280b574d94e47b4.js @@ -0,0 +1 @@ +"use strict";(function(){const rootPath=getVar("root-path");const NAME_OFFSET=0;const DIRS_OFFSET=1;const FILES_OFFSET=2;const RUSTDOC_MOBILE_BREAKPOINT=700;function closeSidebarIfMobile(){if(window.innerWidth"){addClass(document.documentElement,"src-sidebar-expanded");child.innerText="<";updateLocalStorage("source-sidebar-show","true")}else{removeClass(document.documentElement,"src-sidebar-expanded");child.innerText=">";updateLocalStorage("source-sidebar-show","false")}}function createSidebarToggle(){const sidebarToggle=document.createElement("div");sidebarToggle.id="src-sidebar-toggle";const inner=document.createElement("button");if(getCurrentValue("source-sidebar-show")==="true"){inner.innerText="<"}else{inner.innerText=">"}inner.onclick=toggleSidebar;sidebarToggle.appendChild(inner);return sidebarToggle}function createSrcSidebar(){const container=document.querySelector("nav.sidebar");const sidebarToggle=createSidebarToggle();container.insertBefore(sidebarToggle,container.firstChild);const sidebar=document.createElement("div");sidebar.id="src-sidebar";let hasFoundFile=false;const title=document.createElement("div");title.className="title";title.innerText="Files";sidebar.appendChild(title);Object.keys(srcIndex).forEach(key=>{srcIndex[key][NAME_OFFSET]=key;hasFoundFile=createDirEntry(srcIndex[key],sidebar,"",hasFoundFile)});container.appendChild(sidebar);const selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}}const lineNumbersRegex=/^#?(\d+)(?:-(\d+))?$/;function highlightSrcLines(match){if(typeof match==="undefined"){match=window.location.hash.match(lineNumbersRegex)}if(!match){return}let from=parseInt(match[1],10);let to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to{onEachLazy(e.getElementsByTagName("a"),i_e=>{removeClass(i_e,"line-highlighted")})});for(let i=from;i<=to;++i){elem=document.getElementById(i);if(!elem){break}addClass(elem,"line-highlighted")}}const handleSrcHighlight=(function(){let prev_line_id=0;const set_fragment=name=>{const x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSrcLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return ev=>{let cur_line_id=parseInt(ev.target.id,10);if(isNaN(cur_line_id)||ev.ctrlKey||ev.altKey||ev.metaKey){return}ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){const tmp=prev_line_id;prev_line_id=cur_line_id;cur_line_id=tmp}set_fragment(prev_line_id+"-"+cur_line_id)}else{prev_line_id=cur_line_id;set_fragment(cur_line_id)}}}());window.addEventListener("hashchange",()=>{const match=window.location.hash.match(lineNumbersRegex);if(match){return highlightSrcLines(match)}});onEachLazy(document.getElementsByClassName("src-line-numbers"),el=>{el.addEventListener("click",handleSrcHighlight)});highlightSrcLines();window.createSrcSidebar=createSrcSidebar})() \ No newline at end of file diff --git a/static.files/storage-fec3eaa3851e447d.js b/static.files/storage-fec3eaa3851e447d.js new file mode 100644 index 00000000..a687118f --- /dev/null +++ b/static.files/storage-fec3eaa3851e447d.js @@ -0,0 +1 @@ +"use strict";const builtinThemes=["light","dark","ayu"];const darkThemes=["dark","ayu"];window.currentTheme=document.getElementById("themeStyle");const settingsDataset=(function(){const settingsElement=document.getElementById("default-settings");return settingsElement&&settingsElement.dataset?settingsElement.dataset:null})();function getSettingValue(settingName){const current=getCurrentValue(settingName);if(current===null&&settingsDataset!==null){const def=settingsDataset[settingName.replace(/-/g,"_")];if(def!==undefined){return def}}return current}const localStoredTheme=getSettingValue("theme");function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(elem&&elem.classList){elem.classList.add(className)}}function removeClass(elem,className){if(elem&&elem.classList){elem.classList.remove(className)}}function onEach(arr,func,reversed){if(arr&&arr.length>0){if(reversed){for(let i=arr.length-1;i>=0;--i){if(func(arr[i])){return true}}}else{for(const elem of arr){if(func(elem)){return true}}}}return false}function onEachLazy(lazyArray,func,reversed){return onEach(Array.prototype.slice.call(lazyArray),func,reversed)}function updateLocalStorage(name,value){try{window.localStorage.setItem("rustdoc-"+name,value)}catch(e){}}function getCurrentValue(name){try{return window.localStorage.getItem("rustdoc-"+name)}catch(e){return null}}const getVar=(function getVar(name){const el=document.querySelector("head > meta[name='rustdoc-vars']");return el?el.attributes["data-"+name].value:null});function switchTheme(newThemeName,saveTheme){if(saveTheme){updateLocalStorage("theme",newThemeName)}document.documentElement.setAttribute("data-theme",newThemeName);if(builtinThemes.indexOf(newThemeName)!==-1){if(window.currentTheme){window.currentTheme.parentNode.removeChild(window.currentTheme);window.currentTheme=null}}else{const newHref=getVar("root-path")+newThemeName+getVar("resource-suffix")+".css";if(!window.currentTheme){if(document.readyState==="loading"){document.write(``);window.currentTheme=document.getElementById("themeStyle")}else{window.currentTheme=document.createElement("link");window.currentTheme.rel="stylesheet";window.currentTheme.id="themeStyle";window.currentTheme.href=newHref;document.documentElement.appendChild(window.currentTheme)}}else if(newHref!==window.currentTheme.href){window.currentTheme.href=newHref}}}const updateTheme=(function(){const mql=window.matchMedia("(prefers-color-scheme: dark)");function updateTheme(){if(getSettingValue("use-system-theme")!=="false"){const lightTheme=getSettingValue("preferred-light-theme")||"light";const darkTheme=getSettingValue("preferred-dark-theme")||"dark";updateLocalStorage("use-system-theme","true");switchTheme(mql.matches?darkTheme:lightTheme,true)}else{switchTheme(getSettingValue("theme"),false)}}mql.addEventListener("change",updateTheme);return updateTheme})();if(getSettingValue("use-system-theme")!=="false"&&window.matchMedia){if(getSettingValue("use-system-theme")===null&&getSettingValue("preferred-dark-theme")===null&&darkThemes.indexOf(localStoredTheme)>=0){updateLocalStorage("preferred-dark-theme",localStoredTheme)}}updateTheme();if(getSettingValue("source-sidebar-show")==="true"){addClass(document.documentElement,"src-sidebar-expanded")}window.addEventListener("pageshow",ev=>{if(ev.persisted){setTimeout(updateTheme,0)}}) \ No newline at end of file diff --git a/static.files/wheel-7b819b6101059cd0.svg b/static.files/wheel-7b819b6101059cd0.svg new file mode 100644 index 00000000..83c07f63 --- /dev/null +++ b/static.files/wheel-7b819b6101059cd0.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/strftime/all.html b/strftime/all.html new file mode 100644 index 00000000..1431b045 --- /dev/null +++ b/strftime/all.html @@ -0,0 +1 @@ +List of all items in this crate
\ No newline at end of file diff --git a/strftime/buffered/fn.strftime.html b/strftime/buffered/fn.strftime.html new file mode 100644 index 00000000..46afc01c --- /dev/null +++ b/strftime/buffered/fn.strftime.html @@ -0,0 +1,25 @@ +strftime in strftime::buffered - Rust

Function strftime::buffered::strftime

source ·
pub fn strftime<'a>(
+    time: &impl Time,
+    format: &[u8],
+    buf: &'a mut [u8]
+) -> Result<&'a mut [u8], Error>
Expand description

Format a time implementation with the specified format byte string, +writing in the provided buffer and returning the written subslice.

+

See the crate-level documentation for a complete description of +possible format specifiers.

+

Allocations

+

This strftime implementation makes no heap allocations and is usable +in a no_std context.

+

Examples

+
use strftime::buffered::strftime;
+use strftime::Time;
+
+// Not shown: create a time implementation with the year 1970
+// let time = ...;
+assert_eq!(time.year(), 1970);
+
+let mut buf = [0u8; 8];
+assert_eq!(strftime(&time, b"%Y", &mut buf)?, b"1970");
+assert_eq!(buf, *b"1970\0\0\0\0");
+

Errors

+

Can produce an Error when the formatting fails.

+
\ No newline at end of file diff --git a/strftime/buffered/index.html b/strftime/buffered/index.html new file mode 100644 index 00000000..17c7a523 --- /dev/null +++ b/strftime/buffered/index.html @@ -0,0 +1,4 @@ +strftime::buffered - Rust

Module strftime::buffered

source ·
Expand description

Provides a strftime implementation using a format string with arbitrary +bytes, writing to a provided byte slice.

+

Functions

  • Format a time implementation with the specified format byte string, +writing in the provided buffer and returning the written subslice.
\ No newline at end of file diff --git a/strftime/buffered/sidebar-items.js b/strftime/buffered/sidebar-items.js new file mode 100644 index 00000000..7d7b2ead --- /dev/null +++ b/strftime/buffered/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["strftime"]}; \ No newline at end of file diff --git a/strftime/bytes/fn.strftime.html b/strftime/bytes/fn.strftime.html new file mode 100644 index 00000000..425474ed --- /dev/null +++ b/strftime/bytes/fn.strftime.html @@ -0,0 +1,20 @@ +strftime in strftime::bytes - Rust

Function strftime::bytes::strftime

source ·
pub fn strftime(time: &impl Time, format: &[u8]) -> Result<Vec<u8>, Error>
Available on crate feature alloc only.
Expand description

Format a time implementation with the specified format byte string.

+

See the crate-level documentation for a complete description of +possible format specifiers.

+

Allocations

+

This strftime implementation writes its output to a heap-allocated +Vec. The implementation exclusively uses fallible allocation APIs +like Vec::try_reserve. This function will return Error::OutOfMemory +if there is an allocation failure.

+

Examples

+
use strftime::bytes::strftime;
+use strftime::Time;
+
+// Not shown: create a time implementation with the year 1970
+// let time = ...;
+assert_eq!(time.year(), 1970);
+
+assert_eq!(strftime(&time, b"%Y")?, b"1970");
+

Errors

+

Can produce an Error when the formatting fails.

+
\ No newline at end of file diff --git a/strftime/bytes/index.html b/strftime/bytes/index.html new file mode 100644 index 00000000..b039708b --- /dev/null +++ b/strftime/bytes/index.html @@ -0,0 +1,3 @@ +strftime::bytes - Rust

Module strftime::bytes

source ·
Available on crate feature alloc only.
Expand description

Provides a strftime implementation using a format string with arbitrary +bytes, writing to a newly allocated Vec.

+

Functions

  • Format a time implementation with the specified format byte string.
\ No newline at end of file diff --git a/strftime/bytes/sidebar-items.js b/strftime/bytes/sidebar-items.js new file mode 100644 index 00000000..7d7b2ead --- /dev/null +++ b/strftime/bytes/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["strftime"]}; \ No newline at end of file diff --git a/strftime/constant.ASCTIME_FORMAT_STRING.html b/strftime/constant.ASCTIME_FORMAT_STRING.html new file mode 100644 index 00000000..37693132 --- /dev/null +++ b/strftime/constant.ASCTIME_FORMAT_STRING.html @@ -0,0 +1,2 @@ +ASCTIME_FORMAT_STRING in strftime - Rust
pub const ASCTIME_FORMAT_STRING: &str = "%c";
Expand description

Format string used by Ruby Time#asctime method.

+
\ No newline at end of file diff --git a/strftime/enum.Error.html b/strftime/enum.Error.html new file mode 100644 index 00000000..4fb69cf7 --- /dev/null +++ b/strftime/enum.Error.html @@ -0,0 +1,31 @@ +Error in strftime - Rust

Enum strftime::Error

source ·
#[non_exhaustive]
pub enum Error { + InvalidTime, + InvalidFormatString, + FormattedStringTooLarge, + WriteZero, + FmtError(Error), + OutOfMemory(TryReserveError), + IoError(Error), +}
Expand description

Error type returned by the strftime functions.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

InvalidTime

Provided time implementation returns invalid values.

+
§

InvalidFormatString

Provided format string is ended by an unterminated format specifier.

+
§

FormattedStringTooLarge

Formatted string is too large and could cause an out-of-memory error.

+
§

WriteZero

Provided buffer for the buffered::strftime function is too small for +the formatted string.

+

This corresponds to the std::io::ErrorKind::WriteZero variant.

+
§

FmtError(Error)

Formatting error, corresponding to core::fmt::Error.

+
§

OutOfMemory(TryReserveError)

Available on crate feature alloc only.

An allocation failure has occurred in either bytes::strftime or +string::strftime.

+
§

IoError(Error)

Available on crate feature std only.

An I/O error has occurred in io::strftime.

+

Trait Implementations§

source§

impl Debug for Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for Error

Available on crate feature std only.
source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<Error> for Error

Available on crate feature std only.
source§

fn from(err: Error) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Error

source§

fn from(err: Error) -> Self

Converts to this type from the input type.
source§

impl From<TryReserveError> for Error

Available on crate feature alloc only.
source§

fn from(err: TryReserveError) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl !RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl !UnwindSafe for Error

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/strftime/fmt/fn.strftime.html b/strftime/fmt/fn.strftime.html new file mode 100644 index 00000000..492cf556 --- /dev/null +++ b/strftime/fmt/fn.strftime.html @@ -0,0 +1,25 @@ +strftime in strftime::fmt - Rust

Function strftime::fmt::strftime

source ·
pub fn strftime(
+    time: &impl Time,
+    format: &str,
+    buf: &mut dyn Write
+) -> Result<(), Error>
Expand description

Format a time implementation with the specified UTF-8 format string, +writing to the provided core::fmt::Write object.

+

See the crate-level documentation for a complete description of +possible format specifiers.

+

Allocations

+

This strftime implementation makes no heap allocations on its own, but +the provided writer may allocate.

+

Examples

+
use strftime::fmt::strftime;
+use strftime::Time;
+
+// Not shown: create a time implementation with the year 1970
+// let time = ...;
+assert_eq!(time.year(), 1970);
+
+let mut buf = String::new();
+strftime(&time, "%Y", &mut buf)?;
+assert_eq!(buf, "1970");
+

Errors

+

Can produce an Error when the formatting fails.

+
\ No newline at end of file diff --git a/strftime/fmt/index.html b/strftime/fmt/index.html new file mode 100644 index 00000000..55ff6e76 --- /dev/null +++ b/strftime/fmt/index.html @@ -0,0 +1,4 @@ +strftime::fmt - Rust

Module strftime::fmt

source ·
Expand description

Provides a strftime implementation using a UTF-8 format string, writing to +a core::fmt::Write object.

+

Functions

  • Format a time implementation with the specified UTF-8 format string, +writing to the provided core::fmt::Write object.
\ No newline at end of file diff --git a/strftime/fmt/sidebar-items.js b/strftime/fmt/sidebar-items.js new file mode 100644 index 00000000..7d7b2ead --- /dev/null +++ b/strftime/fmt/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["strftime"]}; \ No newline at end of file diff --git a/strftime/index.html b/strftime/index.html new file mode 100644 index 00000000..d3dd8b32 --- /dev/null +++ b/strftime/index.html @@ -0,0 +1,77 @@ +strftime - Rust

Crate strftime

source ·
Expand description

This crate provides a Ruby 3.1.2 compatible strftime function, which +formats time according to the directives in the given format string.

+

The directives begin with a percent % character. Any text not listed as a +directive will be passed through to the output string.

+

Each directive consists of a percent % character, zero or more flags, +optional minimum field width, optional modifier and a conversion specifier +as follows:

+
%<flags><width><modifier><conversion>
+

Usage

+

The various strftime functions in this crate take a generic time +parameter that implements the Time trait.

+

Format Specifiers

Flags

+ + + + + +
FlagDescription
-Use left padding, ignoring width and removing all other padding options in most cases.
_Use spaces for padding.
0Use zeros for padding.
^Convert the resulting string to uppercase.
#Change case of the resulting string.
+

Width

+

The minimum field width specifies the minimum width.

+

Modifiers

+

The modifiers are E and O. They are ignored.

+

Specifiers

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecifierExampleDescription
%Y-2001Year with century if provided, zero-padded to at least 4 digits plus the possible negative sign.
%C-21Year / 100 using Euclidean division, zero-padded to at least 2 digits.
%y99Year % 100 in 00..=99, using Euclidean remainder, zero-padded to 2 digits.
%m01Month of the year in 01..=12, zero-padded to 2 digits.
%BJulyLocale independent full month name.
%b, %hJulLocale independent abbreviated month name, using the first 3 letters.
%d01Day of the month in 01..=31, zero-padded to 2 digits.
%e 1Day of the month in 1..=31, blank-padded to 2 digits.
%j001Day of the year in 001..=366, zero-padded to 3 digits.
%H00Hour of the day (24-hour clock) in 00..=23, zero-padded to 2 digits.
%k 0Hour of the day (24-hour clock) in 0..=23, blank-padded to 2 digits.
%I01Hour of the day (12-hour clock) in 01..=12, zero-padded to 2 digits.
%l 1Hour of the day (12-hour clock) in 1..=12, blank-padded to 2 digits.
%PamLowercase meridian indicator ("am" or "pm").
%pAMUppercase meridian indicator ("AM" or "PM").
%M00Minute of the hour in 00..=59, zero-padded to 2 digits.
%S00Second of the minute in 00..=60, zero-padded to 2 digits.
%L123Truncated fractional seconds digits, with 3 digits by default. Number of digits is specified by the width field.
%N123456789Truncated fractional seconds digits, with 9 digits by default. Number of digits is specified by the width field.
%z+0200Zero-padded signed time zone UTC hour and minute offsets (+hhmm).
%:z+02:00Zero-padded signed time zone UTC hour and minute offsets with colons (+hh:mm).
%::z+02:00:00Zero-padded signed time zone UTC hour, minute and second offsets with colons (+hh:mm:ss).
%:::z+02Zero-padded signed time zone UTC hour offset, with optional minute and second offsets with colons (+hh[:mm[:ss]]).
%ZCESTPlatform-dependent abbreviated time zone name.
%ASundayLocale independent full weekday name.
%aSunLocale independent abbreviated weekday name, using the first 3 letters.
%u1Day of the week from Monday in 1..=7, zero-padded to 1 digit.
%w0Day of the week from Sunday in 0..=6, zero-padded to 1 digit.
%G-2001Same as %Y, but using the ISO 8601 week-based year. 1
%g99Same as %y, but using the ISO 8601 week-based year. 1
%V01ISO 8601 week number in 01..=53, zero-padded to 2 digits. 1
%U00Week number from Sunday in 00..=53, zero-padded to 2 digits. The week 1 starts with the first Sunday of the year.
%W00Week number from Monday in 00..=53, zero-padded to 2 digits. The week 1 starts with the first Monday of the year.
%s86400Number of seconds since 1970-01-01 00:00:00 UTC, zero-padded to at least 1 digit.
%n\nNewline character '\n'.
%t\tTab character '\t'.
%%%Literal '%' character.
%cSun Jul 8 00:23:45 2001Date and time, equivalent to "%a %b %e %H:%M:%S %Y".
%D, %x07/08/01Date, equivalent to "%m/%d/%y".
%F2001-07-08ISO 8601 date, equivalent to "%Y-%m-%d".
%v 8-JUL-2001VMS date, equivalent to "%e-%^b-%4Y".
%r12:23:45 AM12-hour time, equivalent to "%I:%M:%S %p".
%R00:2324-hour time without seconds, equivalent to "%H:%M".
%T, %X00:23:4524-hour time, equivalent to "%H:%M:%S".
+

  1. %G, %g, %V: Week 1 of ISO 8601 is the first week with at least 4 +days in that year. The days before the first week are in the last week of +the previous year. 

Modules

  • Provides a strftime implementation using a format string with arbitrary +bytes, writing to a provided byte slice.
  • bytesalloc
    Provides a strftime implementation using a format string with arbitrary +bytes, writing to a newly allocated Vec.
  • Provides a strftime implementation using a UTF-8 format string, writing to +a core::fmt::Write object.
  • iostd
    Provides a strftime implementation using a format string with arbitrary +bytes, writing to a std::io::Write object.
  • stringalloc
    Provides a strftime implementation using a UTF-8 format string, writing to +a newly allocated String.

Enums

  • Error type returned by the strftime functions.

Constants

Traits

  • Common methods needed for formatting time.
\ No newline at end of file diff --git a/strftime/io/fn.strftime.html b/strftime/io/fn.strftime.html new file mode 100644 index 00000000..e149d950 --- /dev/null +++ b/strftime/io/fn.strftime.html @@ -0,0 +1,25 @@ +strftime in strftime::io - Rust

Function strftime::io::strftime

source ·
pub fn strftime(
+    time: &impl Time,
+    format: &[u8],
+    buf: &mut dyn Write
+) -> Result<(), Error>
Available on crate feature std only.
Expand description

Format a time implementation with the specified format byte string, +writing to the provided std::io::Write object.

+

See the crate-level documentation for a complete description of +possible format specifiers.

+

Allocations

+

This strftime implementation makes no heap allocations on its own, but +the provided writer may allocate.

+

Examples

+
use strftime::io::strftime;
+use strftime::Time;
+
+// Not shown: create a time implementation with the year 1970
+// let time = ...;
+assert_eq!(time.year(), 1970);
+
+let mut buf = Vec::new();
+strftime(&time, b"%Y", &mut buf)?;
+assert_eq!(buf, *b"1970");
+

Errors

+

Can produce an Error when the formatting fails.

+
\ No newline at end of file diff --git a/strftime/io/index.html b/strftime/io/index.html new file mode 100644 index 00000000..f53ea264 --- /dev/null +++ b/strftime/io/index.html @@ -0,0 +1,4 @@ +strftime::io - Rust

Module strftime::io

source ·
Available on crate feature std only.
Expand description

Provides a strftime implementation using a format string with arbitrary +bytes, writing to a std::io::Write object.

+

Functions

  • Format a time implementation with the specified format byte string, +writing to the provided std::io::Write object.
\ No newline at end of file diff --git a/strftime/io/sidebar-items.js b/strftime/io/sidebar-items.js new file mode 100644 index 00000000..7d7b2ead --- /dev/null +++ b/strftime/io/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["strftime"]}; \ No newline at end of file diff --git a/strftime/sidebar-items.js b/strftime/sidebar-items.js new file mode 100644 index 00000000..1b503a4b --- /dev/null +++ b/strftime/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"constant":["ASCTIME_FORMAT_STRING"],"enum":["Error"],"mod":["buffered","bytes","fmt","io","string"],"trait":["Time"]}; \ No newline at end of file diff --git a/strftime/string/fn.strftime.html b/strftime/string/fn.strftime.html new file mode 100644 index 00000000..64fe3462 --- /dev/null +++ b/strftime/string/fn.strftime.html @@ -0,0 +1,20 @@ +strftime in strftime::string - Rust

Function strftime::string::strftime

source ·
pub fn strftime(time: &impl Time, format: &str) -> Result<String, Error>
Available on crate feature alloc only.
Expand description

Format a time implementation with the specified UTF-8 format string.

+

See the crate-level documentation for a complete description of +possible format specifiers.

+

Allocations

+

This strftime implementation writes its output to a heap-allocated +Vec. The implementation exclusively uses fallible allocation APIs +like Vec::try_reserve. This function will return Error::OutOfMemory +if there is an allocation failure.

+

Examples

+
use strftime::string::strftime;
+use strftime::Time;
+
+// Not shown: create a time implementation with the year 1970
+// let time = ...;
+assert_eq!(time.year(), 1970);
+
+assert_eq!(strftime(&time, "%Y")?, "1970");
+

Errors

+

Can produce an Error when the formatting fails.

+
\ No newline at end of file diff --git a/strftime/string/index.html b/strftime/string/index.html new file mode 100644 index 00000000..12514450 --- /dev/null +++ b/strftime/string/index.html @@ -0,0 +1,3 @@ +strftime::string - Rust

Module strftime::string

source ·
Available on crate feature alloc only.
Expand description

Provides a strftime implementation using a UTF-8 format string, writing to +a newly allocated String.

+

Functions

  • Format a time implementation with the specified UTF-8 format string.
\ No newline at end of file diff --git a/strftime/string/sidebar-items.js b/strftime/string/sidebar-items.js new file mode 100644 index 00000000..7d7b2ead --- /dev/null +++ b/strftime/string/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["strftime"]}; \ No newline at end of file diff --git a/strftime/trait.Time.html b/strftime/trait.Time.html new file mode 100644 index 00000000..62ddfe10 --- /dev/null +++ b/strftime/trait.Time.html @@ -0,0 +1,33 @@ +Time in strftime - Rust

Trait strftime::Time

source ·
pub trait Time {
+
Show 13 methods // Required methods + fn year(&self) -> i32; + fn month(&self) -> u8; + fn day(&self) -> u8; + fn hour(&self) -> u8; + fn minute(&self) -> u8; + fn second(&self) -> u8; + fn nanoseconds(&self) -> u32; + fn day_of_week(&self) -> u8; + fn day_of_year(&self) -> u16; + fn to_int(&self) -> i64; + fn is_utc(&self) -> bool; + fn utc_offset(&self) -> i32; + fn time_zone(&self) -> &str; +
}
Expand description

Common methods needed for formatting time.

+

This should be implemented for structs representing a time.

+

All the strftime functions take as input an implementation of this trait.

+

Required Methods§

source

fn year(&self) -> i32

Returns the year for time (including the century).

+
source

fn month(&self) -> u8

Returns the month of the year in 1..=12 for time.

+
source

fn day(&self) -> u8

Returns the day of the month in 1..=31 for time.

+
source

fn hour(&self) -> u8

Returns the hour of the day in 0..=23 for time.

+
source

fn minute(&self) -> u8

Returns the minute of the hour in 0..=59 for time.

+
source

fn second(&self) -> u8

Returns the second of the minute in 0..=60 for time.

+
source

fn nanoseconds(&self) -> u32

Returns the number of nanoseconds in 0..=999_999_999 for time.

+
source

fn day_of_week(&self) -> u8

Returns an integer representing the day of the week in 0..=6, with +Sunday == 0.

+
source

fn day_of_year(&self) -> u16

Returns an integer representing the day of the year in 1..=366.

+
source

fn to_int(&self) -> i64

Returns the number of seconds as a signed integer since the Epoch.

+
source

fn is_utc(&self) -> bool

Returns true if the time zone is UTC.

+
source

fn utc_offset(&self) -> i32

Returns the offset in seconds between the timezone of time and UTC.

+
source

fn time_zone(&self) -> &str

Returns the name of the time zone as a string.

+

Implementors§

\ No newline at end of file diff --git a/trait.impl/core/convert/trait.From.js b/trait.impl/core/convert/trait.From.js new file mode 100644 index 00000000..0a77bce5 --- /dev/null +++ b/trait.impl/core/convert/trait.From.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"strftime":[["impl From<TryReserveError> for Error"],["impl From<Error> for Error"],["impl From<Error> for Error"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/error/trait.Error.js b/trait.impl/core/error/trait.Error.js new file mode 100644 index 00000000..96be86a4 --- /dev/null +++ b/trait.impl/core/error/trait.Error.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"strftime":[["impl Error for Error"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/fmt/trait.Debug.js b/trait.impl/core/fmt/trait.Debug.js new file mode 100644 index 00000000..eabd2910 --- /dev/null +++ b/trait.impl/core/fmt/trait.Debug.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"strftime":[["impl Debug for Error"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/fmt/trait.Display.js b/trait.impl/core/fmt/trait.Display.js new file mode 100644 index 00000000..3f046ba5 --- /dev/null +++ b/trait.impl/core/fmt/trait.Display.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"strftime":[["impl Display for Error"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Freeze.js b/trait.impl/core/marker/trait.Freeze.js new file mode 100644 index 00000000..301bc583 --- /dev/null +++ b/trait.impl/core/marker/trait.Freeze.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"strftime":[["impl Freeze for Error",1,["strftime::Error"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Send.js b/trait.impl/core/marker/trait.Send.js new file mode 100644 index 00000000..8c4f0757 --- /dev/null +++ b/trait.impl/core/marker/trait.Send.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"strftime":[["impl Send for Error",1,["strftime::Error"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Sync.js b/trait.impl/core/marker/trait.Sync.js new file mode 100644 index 00000000..3c4e983d --- /dev/null +++ b/trait.impl/core/marker/trait.Sync.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"strftime":[["impl Sync for Error",1,["strftime::Error"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Unpin.js b/trait.impl/core/marker/trait.Unpin.js new file mode 100644 index 00000000..dc11f480 --- /dev/null +++ b/trait.impl/core/marker/trait.Unpin.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"strftime":[["impl Unpin for Error",1,["strftime::Error"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js b/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js new file mode 100644 index 00000000..54c22061 --- /dev/null +++ b/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"strftime":[["impl !RefUnwindSafe for Error",1,["strftime::Error"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js b/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js new file mode 100644 index 00000000..bf05c74d --- /dev/null +++ b/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"strftime":[["impl !UnwindSafe for Error",1,["strftime::Error"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file