0

I have a struct that contains a string that is used to format dates with chrono::DateTime.format():

struct DateThingy {
    format: String,
}

impl DateThingy {
    fn new(format: String) -> Self {
        Self { format }
    }
}

This is a bit of a waste since the format string has to be parsed every time I format a date. To be more efficient, I figured I should parse the format string once and store the result instead. Then I can format using chrono::DateTime::format_with_items:

use chrono::format::strftime::StrftimeItems;
use chrono::format::Item;

struct DateThingy<'a> {
    items: Vec<Item<'a>>,
}

impl<'a> DateThingy<'a> {
    fn new(format: String) -> Self {
        Self {
            items: StrftimeItems::new(&format).collect(),
        }
    }
}

This does not work:

error[E0515]: cannot return value referencing function parameter `format`
  --> src/lib.rs:10:9
   |
10 | /         Self {
11 | |             items: StrftimeItems::new(&format).collect(),
   | |                                       ------- `format` is borrowed here
12 | |         }
   | |_________^ returns a value referencing data owned by the current function

I can change the signature of new to fn new(format: &'a str) -> Self to get rid of the error, but now the creator of a DateThingy must make sure that the format string is alive for long enough and mess around with lifetimes. I just want the DateThingy to own all the information it needs, without relying on references or lifetimes.

How do I accomplish that?

The creation of the DateThingy is not performance critical, so I am happy to clone string, allocate, store them, etc., if that helps.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Anders
  • 8,307
  • 9
  • 56
  • 88
  • [Why can't I store a value and a reference to that value in the same struct?](https://stackoverflow.com/q/32300132/155423); [Is there any way to return a reference to a variable created in a function?](https://stackoverflow.com/q/32682876/155423); [Return local String as a slice (&str)](https://stackoverflow.com/q/29428227/155423); [Proper way to return a new string in Rust](https://stackoverflow.com/q/43079077/155423) – Shepmaster Jul 06 '20 at 18:14
  • @Shepmaster Thanks for the input! I get that I can't just store the string alongside the items in the struct. But are there perhaps solutions using other parts of the `chrono` library? Some `OwnedItem` or similar? – Anders Jul 06 '20 at 18:20
  • Yep, hopefully. Otherwise see [How can I store a Chars iterator in the same struct as the String it is iterating on?](https://stackoverflow.com/q/43952104/155423); [Is there an owned version of String::chars?](https://stackoverflow.com/q/47193584/155423). – Shepmaster Jul 06 '20 at 18:27
  • However, I don't see why you'd want to store the items — don't you want to do something with them? – Shepmaster Jul 06 '20 at 18:28
  • @Shepmaster Thanks again for the interesting links. Yes, I want to use the items as parameter to `format_with_items` in multiple calls, hence I need them stored. I left that part of the code out in the spirit of minimalism. – Anders Jul 06 '20 at 18:49

0 Answers0