-
Notifications
You must be signed in to change notification settings - Fork 91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow to deserialize enums from their string representation #223
Conversation
Enums are normally serialized as integers, but in some parts of kak-lsp we like to use strings. I'm working on a feature to select specific kinds of symbols. The editor support script wants to send something like ["Function", "Method"], which I want to deserialize into SymbolKinds. Add an implementation of TryFrom<&String> for enums. This is the dual of the Debug. An alternative solution would be to allow clients to enumerate all enum variants, is there a way to do that? I initially tried to implement TryFrom<&str> but got weird errors when the input string does not have static lifetime, like SymbolKind::try_from(&("Function".to_string())) Compiling lsp-types v0.91.1 (/home/johannes/git/lsp-types) Compiling kak-lsp v11.0.1-snapshot (/home/johannes/git/kak-lsp) error[E0277]: the trait bound `lsp_types::SymbolKind: From<&std::string::String>` is not satisfied --> src/language_features/document_symbol.rs:169:25 | 169 | SymbolKind::try_from(&("Function".to_string())) | ^^^^^^^^^^^^^^^^^^^^ the trait `From<&std::string::String>` is not implemented for `lsp_types::SymbolKind` | = note: required because of the requirements on the impl of `Into<lsp_types::SymbolKind>` for `&std::string::String` = note: required because of the requirements on the impl of `TryFrom<&std::string::String>` for `lsp_types::SymbolKind` note: required by `try_from` --> /home/johannes/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/convert/mod.rs:477:5 | 477 | fn try_from(value: T) -> Result<Self, Self::Error>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `lsp_types::SymbolKind: From<&std::string::String>` is not satisfied --> src/language_features/document_symbol.rs:169:25 | 169 | SymbolKind::try_from(&("Function".to_string())) | ^^^^^^^^^^^^^^^^^^^^ the trait `From<&std::string::String>` is not implemented for `lsp_types::SymbolKind` | = note: required because of the requirements on the impl of `Into<lsp_types::SymbolKind>` for `&std::string::String` = note: required because of the requirements on the impl of `TryFrom<&std::string::String>` for `lsp_types::SymbolKind`
impl std::convert::TryFrom<&String> for $typ { | ||
type Error = &'static str; | ||
fn try_from(value: &String) -> Result<Self, Self::Error> { | ||
match value { | ||
$( | ||
_ if *value == format!("{:?}", Self::$name) => Ok(Self::$name), | ||
)* | ||
_ => Err("unknown enum variant"), | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
impl std::convert::TryFrom<&String> for $typ { | |
type Error = &'static str; | |
fn try_from(value: &String) -> Result<Self, Self::Error> { | |
match value { | |
$( | |
_ if *value == format!("{:?}", Self::$name) => Ok(Self::$name), | |
)* | |
_ => Err("unknown enum variant"), | |
} | |
} | |
} | |
impl std::convert::TryFrom<&str> for $typ { | |
type Error = &'static str; | |
fn try_from(value: &str) -> Result<Self, Self::Error> { | |
match value { | |
$( | |
stringify!($name) => Ok(Self::$name), | |
)* | |
_ => Err("unknown enum variant"), | |
} | |
} | |
} |
No need to allocate for this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I was thinking to add a &'static str
member to avoid the allocation.
Your suggestion is even more natural - though it requires FUNCTION
as input instead of Function
.
I don't have a strong opinion on which one is better. I guess we could keep symmetry with Debug
while still only allocating once (converting value
). Not sure what's better long-term.
|
The errors you get when you define This will work (here let res = SymbolKind::try_from("Function"); So will this: // You won't really write code like this but this is just to show that if you
// passed a &str to try_from it would work
// Mostly you should already have a &str, perhaps from a function parameter...
let fun = "Function".to_string();
let res = SymbolKind::try_from(fun.as_str()); But as you report, this does not: let res = SymbolKind::try_from(&("Function".to_string())); Rust is just not being smart here to use the But if you want to do it as a one liner, this will work: // This approach is pointless but here to show it can be done...
let res = SymbolKind::try_from("Function".to_string().deref()) |
Enums are normally serialized as integers, but in some parts of
kak-lsp we like to use strings.
I'm working on a feature to select specific kinds of symbols.
The editor support script wants to send something like ["Function",
"Method"], which I want to deserialize into SymbolKinds.
Add an implementation of TryFrom<&String> for enums. This is the dual
of the Debug.
An alternative solution would be to allow clients to enumerate all
enum variants, is there a way to do that?
I initially tried to implement TryFrom<&str> but got weird errors
when the input string does not have static lifetime, like