Created
June 26, 2017 21:49
-
-
Save piedoom/fdabcf4fcb3319c0344a8cb48294f652 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Representing JSON in Rust objects | |
All objects will always have an ID and Type, but all other fields vary | |
[ | |
{ | |
id: 12345, | |
type: "photo", | |
photo_url: "asdasda.com" | |
}, | |
{ | |
id: 12346, | |
type: "text", | |
body: "some text" | |
} | |
] | |
*/ | |
// The first way one can solve this problem is accessor methods on a trait | |
// this feels very hacky :( | |
trait BasePost { | |
fn id() -> i32; | |
fn type() -> SomeEnum; | |
} | |
impl BasePost for PhotoPost { | |
// impl those trait methods | |
} | |
impl PhotoPost { | |
// impl photo specific methods | |
fn photo_url() -> String { | |
// ... | |
} | |
} | |
// This has the advantage that if a type of post was known at compile time, we can do something easily like | |
// `myPhotoPost.photo_url()`. However, accessor methods feel very java-y and seem like a bad choice. | |
// Another option could be an enum with data. Something like this: | |
struct Post { | |
type: PostType, | |
id: i32 | |
} | |
// we only have one struct type but have an enum that holds specialized data. | |
enum PostType { | |
Photo(PhotoData), | |
Text(TextData) | |
} | |
// The upside of this is that there aren't any ugly accessor methods. The downside is that we would need to match results any time | |
// that we wanted to access special data. For example - | |
myPost.id; // works great! We will always have an `id` on our post type. | |
// but to get something like `photo_url` we'd first need to make sure the object had the Photo enum | |
let url = match myPost.type { | |
PostType::Photo => myPost.photo_url | |
} | |
/// Which one of these methods is preferred? Is there a better way to do this? Basically, I'm working around the fact that rust does | |
/// (not yet at least) allow fields in traits. In a perfect world, I could do the following: | |
trait Post { | |
id: i32, | |
type: PostType | |
} | |
struct PhotoPost : Post { | |
photo_url: String | |
} | |
myPhotoObject.id; | |
myPhotoObject.photo_url; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment