-
-
Notifications
You must be signed in to change notification settings - Fork 217
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
Add basic dictionary impl #92
Conversation
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.
Thanks a lot, this is very valuable work to get initial Dictionary
support! 🙂
Added some comments. As a small nitpick, could you end documentation lines with a full stop, even if they are short? E.g:
/// Constructs an empty `Dictionary`
pub fn new() -> Self {...}
becomes
/// Constructs an empty `Dictionary`.
pub fn new() -> Self {...}
bors try |
tryBuild failed: |
|
Floats aren't |
aa1b50f
to
3786a0a
Compare
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.
Thanks for the update!
Instead of impl ToVariant
, can you use explicit generic arguments? That allows the caller to specify them, to dis-ambiguate the call if needed.
So instead of
pub fn get(&self, key: impl ToVariant) -> Option<Variant>
you'd have
pub fn get<K: ToVariant>(&self, key: K) -> Option<Variant>
godot-core/src/builtin/dictionary.rs
Outdated
/// Creates a new dictionary with the given keys and values, the syntax mirrors | ||
/// godot's dictionary creation syntax. | ||
/// | ||
/// Any value can be used as a key, but to use an expression you need to surround it | ||
/// in `()` or `{}` | ||
/// | ||
/// Example | ||
/// ```rust, no_run | ||
/// # #[macro_use] extern crate godot_core; | ||
/// # fn main() { | ||
/// let key = "my_key"; | ||
/// let d = dict! { | ||
/// "key1": 10, | ||
/// "another": Variant::nil(), | ||
/// key: true, | ||
/// (1 + 2): "final", | ||
/// } | ||
/// # } | ||
/// ``` |
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.
Nitpicks:
- uppercase "Godot"
- missing colon after "Example"
- missing full stops at end of sentences
```rust, no_run
->```no_run
(Rust is implied)
Maybe check this in other places as well.
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.
i uppercased "Godot" in all the documentation i could find. i found two places i forgot a full stop too, hopefully i didnt miss anything else.
bors try |
tryBuild failed: |
Run rustfmt
c6d87c9
to
752bdac
Compare
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.
Thanks a lot, it looks very good by now! Few things remaining, then we should be good to go 🚀
Also, CI failed due to a network error, I'll restart it.
bors try
/// Convert the keys of this dictionary to a strongly typed rust `HashSet`. If the | ||
/// conversion fails for any key, an error is returned. | ||
impl<K: FromVariant + Eq + std::hash::Hash> TryFrom<&Dictionary> for HashSet<K> { | ||
type Error = VariantConversionError; | ||
|
||
fn try_from(dictionary: &Dictionary) -> Result<Self, Self::Error> { | ||
// TODO: try to panic or something if modified while iterating | ||
// Though probably better to fix when implementing iteration proper | ||
dictionary | ||
.keys() | ||
.iter_shared() | ||
.map(|key| K::try_from_variant(&key)) | ||
.collect() | ||
} | ||
} |
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.
This is OK for now, but might later be removed, once we have full iterator support.
Reason: maps and sets are different data structures, so I'm not sure if a direct From/TryFrom
conversion is the right approach. For example, there is no such conversion between HashMap
and HashSet
in the standard library.
Instead, we can add iterators over key-value pairs, keys and values. It should then be relatively simple to collect()
them into their respective data structures, and we can make this API more versatile and agnostic of concrete types like HashSet
.
tryBuild failed: |
Hopefully the `from_sys_init` thing used in array will stop the `duplicate` crash
e354378
to
2c2f924
Compare
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.
Thanks again for this great PR and the extensive testing! 👍
bors r+
Build succeeded: |
Manually re-merged in 188aa69, as I forgot to squash 🙃 |
Add basic dictionary impl with:
From
forHashMap
andHashSet
(with true as the values)FromIterator
for(K,V)
dict!
macro to easily make dictionaries godot-stylemissing:
get_mut
(and other_mut
functions)key = value
syntax fordict!
macroThe added
PartialEq => array_operator_equal
impl inArray
is there to simplify a test, but can be removed. But i think it's gonna be added eventually anyway.I'm also not entirely sure about the safety of using dictionaries, my guess is that it's the same as for array though.