• 1 Post
  • 31 Comments
Joined 1 year ago
cake
Cake day: July 21st, 2023

help-circle



  • Two of your macro rules are not used 😉 (expand to see which ones).

    The macro rules are all used. (Macros are matched from top to bottom by the declared match types. The ident/expressions can’t match until after the more text based Option matching.)

    let _foo = Span { line: 1, column: 1, file_path: None };
    let _bar = Span { line: 1, column: 1, file_path: "file.txt".upgrade() };
    let _baz = Span { line: 1, column: 1, file_path: Some("file.txt".to_string()) };
    let _baz = Span { line: 1, column: 1, file_path: None };
    let _baz = Span { line: 1, column: 1, file_path: borrowed.upgrade() };
    let _baz = Span { line: 1, column: 1, file_path: owned.upgrade() };
    

    This doesn’t support Option<&str>. If it did, we would lose literal None support 😉

    I didn’t make Option<&str> an option because the struct is for type Option<String>. It does support Option<String> though.

    impl OptionUpgrade for Option<String> {
        fn upgrade(self) -> Option<String> {
            self
        }
    }
    

    It looks like the following, and uses the last match case.

    let opt: Option<String> = Some("text".into());
    let opt = span!(1, 1, opt);
    

    With macro expansion

    let opt: Option<String> = Some("text".into());
    let opt = Span { line: 1, column: 1, file_path: opt.upgrade() };
    

    There’s not anything stopping it from supporting Option<&str> though. This would be the implementation

    impl OptionUpgrade for Option<&str> {
        fn upgrade(self) -> Option<String> {
            self.map(|v| v.into())
        }
    }