Skip to content
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

Type-level assurance of path being serialized or not in Room::find_path #61

Open
daboross opened this issue Sep 25, 2018 · 2 comments
Open
Labels
C-enhancement Category: A PR with an enhancement or a proposed on in an issue.

Comments

@daboross
Copy link
Collaborator

Room.findPath returns either a serialized path or not depending on the serialized parameter passed in.

As of #53, we translate that to always returning a Path enum that can be serialized or not. While this works, it requires someone who only wants a non-serialized or only wants a serialized path to perform an unwrap on the result.

Since we are using a builder pattern for FindOptions, it should be possible to know at compile time whether or not we're setting serialized by having an additional type parameter for it.

If we do this we can provide type-level assurance that a serialized path is or is not returned. Since we already have Path too, it could be a pure improvement since we could have three type options: Serialized, Vectorized and RuntimeDecided returning Vec<Step>, String and Path respectively.

See #53 (comment).

@daboross daboross added C-enhancement Category: A PR with an enhancement or a proposed on in an issue. A-screeps-game-api labels Sep 25, 2018
@ASalvail
Copy link
Collaborator

Just to be sure I get where you are going: you'd replace the serialize: bool by an enum and type match that enum with whether the path is serialized or not?

@daboross
Copy link
Collaborator Author

daboross commented Sep 25, 2018

It'd have to be something even more type level than that unfortunately. Enums still have their values decided at runtime.

This would mean a trait similar to that mentioned in the comment, like:

trait FindOptionsResult {
    type Result;

    fn deserialize(v: Value) -> Result;
    fn serialized(&self) -> bool;
}

with implementations:

struct SerializedResult;
impl FindOptionsResult for SerializedResult {
    type Result = String;
    // ...
}
struct VectorizedResult;
impl FindOptionsResult for VectorizedResult {
    type Result = Vec<Part>;
    // ...
}
struct RuntimeDecidesResult { serialized: bool }
impl FindOptionsResult for VectorizedResult {
    type Result = Path;
    // ...
}

Then FindOptions would have an option <R: FindOptionsResult> similar to its callback parameter and we could add methods like

impl<R: FindOptionsResult> FindOptions {
    fn always_serialize(mut self) -> FindOptions<SerializedResult> { .. }
    fn always_vectorize(mut self) -> FindOptions<VectorizedResult> { .. }
    fn serialize(mut self, s: bool) -> FindOptions<RuntimeDecidesResult> { .. }
}

Then the call itself would return R::Result rather than Path and if it was not serialized, the result be guaranteed at compile time to be Vec<Part> rather than String.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-enhancement Category: A PR with an enhancement or a proposed on in an issue.
Projects
None yet
Development

No branches or pull requests

2 participants