A library for interacting with the Genius API.
This library revolves around providing two things:
-
Idiomatic Rust structures (a.k.a "data models" or whatever else you like to call them) that represent API endpoint data.
-
A simple HTTP client for interacting with the API.
megamind = "*"
# enable the "catchall" feature
megamind = { version = "*", features = ["catchall"] }
use std::{env::var, error::Error};
use megamind::{ClientBuilder, models::Response};
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let client = ClientBuilder::new().auth_token(var("GENIUS_TOKEN")?).build()?;
let response = client.account().await?;
if let Response::Success { meta, response } = response {
assert_eq!(meta.status, 200);
println!("Howdy, {}!", response.account.user.core.name);
}
Ok(())
}
These are endpoints that can be found on docs.genius.com and accessed anytime.
- Get current user
- Get an annotation
- Get an artist
- Get a list of referents
- Get search results
- Get a user
- Get a web page
- Get a song
- Create an annotation
- Update an annotation
- Delete an annotation
- Upvote/downvote/unvote for an annotation
These are endpoints that cannot be found publicly, but can still be accessed.
Do not rely on always having access to these endpoints, as Genius likely has the agency to revoke access whenever they please.
- Get an album
- Get a referent
These are endpoints that clearly existed at some point (likely found in some nested data model), but is not accessible.
- Get a comment
There are a few general areas in which the library can be improved:
- Data model documentation
- The Genius documentation lacks information for many data fields
- The surface area of the web API is large, even without some of the undocumented endpoints
- Data model specificity
- Many fields could be
enum
s instead ofString
s, but they lack the documentation necessary to be confidently converted - Some fields are simply
()
orVec<()>
because no endpoints have been found to hold data in them - Data model field presence isn't consistent across endpoints and endpoint values
- Many fields could be
- Data model ergonomics
- How nested is too nested for users of this library?
- Naming conventions for the shared and nested structures can be awkward at times (
response.account.user.core.name
isn't as intuitive asresponse.account.name
) - Users might need more derived traits than what is currently offered (e.g.,
Eq
,Hash
, etc.)
- Error handling
- The JSON parsing error given by
Reqwest
isn't always helpful
- The JSON parsing error given by
- Testing
- Endpoints with edge cases aren't always covered by the integration tests, so users will need to encounter them in the wild
- Tests functions could be simplified with better fixtures and/or added macros
- How should this library approach unit tests?
Issues and pull requests are welcome, but please be respectful. It's also generally a good idea to include an endpoint with values if the issue or pull request aims to resolve an issue with parsing a particular endpoint response, or a simple explanation of how the issue or pull request improves efforts in documentation, ergonomics, and/or testing.
What makes this library different from libraries like
genius_rs
andgenius_rust
?
The big difference is that genius_rs
and genius_rust
both make use of large, general models for multiple endpoints, resulting in many fields being Option<...>
. This could be avoided by simply omitting the field in certain endpoints and including it in others. To achieve this, megamind
makes use of highly nested structures that are flattened during serialization and deserialization. This means fewer unwrap
s for you, the API consumer!
What is the
catchall
feature, and why is it a thing?
catchall
enables an extra field on most of the data models that catches all missing JSON fields. This is useful for two reasons:
- it improves this library's development process by pooling unimplemented data into one place (Serde will simply drop them if fields are not defined for them)
- and it gives users flexibility by letting them access a new or missing field without waiting for a library update.
It's also unfortunately just a consequence of the web API itself being a bit unwieldy and underdocumented.
Why is the crate called
megamind
?
Genius... Big-Brained Person... Megamind.