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

Initial implementation #2

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft

Initial implementation #2

wants to merge 5 commits into from

Conversation

theRookieCoder
Copy link

Currently only the modrinth module is implemented

Eskaan and others added 5 commits June 2, 2022 19:40
Make each module a default feature
Change the IDs from strings to a generic type
Change the error from the boxed dynamic to a generic type
Change manual conversion functions to use `Into` instead
@linear
Copy link

linear bot commented Jun 19, 2022

LIB-2 Lib: Dotium

Copy link

@Redblueflame Redblueflame left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested some changes, there's some in there that can seem minor, but I hope that it would help readability / usability when the time comes


#[derive(thiserror::Error, Debug)]
#[error("The trait is not implemented")]
pub struct UnimplementedError;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better if it was a trait that depends on std::error:Error?
So that we can fall back to more normal methods if the need arises, or if we need something like the step the error happened for example

#[error("The trait is not implemented")]
pub struct UnimplementedError;

pub(crate) type Datetime = chrono::DateTime<chrono::Utc>;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UtcDateTime, it can be confused with the generic one it shadows otherwise


async fn get_projects(&self, ids: Vec<&ID>) -> Result<Vec<Project<ID>>, E> {
let mut projects = Vec::new();
for id in ids {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not totally sure about that, but wouldn't this mean that we are working a project at a time?
Could something like https://docs.rs/futures/latest/futures/future/fn.join_all.html help?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sometimes too many concurrent requests completely fails, I had to deal with this problem when implementing concurrent requests, and it was a rather huge pain. I ended up using Semaphore which I don't think you can use with join_all(), and semaphore would need to import tokio which we certainly don't want.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like we have the first design problem lol
But well, it's not like it is a huge problem, and the solution (Having pending requests we can start at any time) is even worse

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well the only platform that doesn't implement multiple requests is github (the others overrides this default implementation), and we won't be using the multiple requests on github afaik.

async fn get_project_dependencies(
&self,
project_id: &ID,
) -> Result<(Vec<Project<ID>>, Vec<Version<ID>>), E>;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would converting this to a Vec<(Project, Version) cause issues somewhere?
I thing that changing this before the project grows too big could be beneficial, as making sure that both vecs are in sync when we have to drop values from within (removing duplicates for example) can be difficult

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I did think about doing this too

Copy link
Contributor

@Eskaan Eskaan Jun 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes because this is not a sorted map. I specifically asked Modrinth on this:

For example, if I have a dependency on any version of Fabric API and a dependency on version 4.0.0 of Mod Menu, it will have both Fabric API and Mod Menu in the projects array and version 4.0.0 of Mod Menu in the versions array
If another version starts depending on version 4.0.1 of Mod Menu then Mod Menu 4.0.1 will appear in the versions array in addition to 4.0.0

That means, the two Vec's can have different lengths. Also they said that I shouldn't rely on their sorting.


async fn get_versions(&self, ids: Vec<(&ID, &ID)>) -> Result<Vec<Version<ID>>, E> {
let mut versions = Vec::new();
for id in ids {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as for get_projects

pub size: Option<usize>,
}

impl Asset {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds like a good place to put a builder in
Either make it manually, or there's a whole lot of procedural macros that can do the job

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've never heard of that, but yeah a better implementation of the contructors for this struct is sorely needed

#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct VersionDependency<ID> {
/// The ID of the project to depend on
pub project_id: Option<ID>,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What relation is there between the project_id and the version?
If it is exclusive (one OR the other), an enum VersionDescriptor could be interesting to make it explicit, and if both can / must be defined, then this system works finely

Copy link
Author

@theRookieCoder theRookieCoder Jun 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Modrinth, they're exclusive but on CurseForge they're not. CurseForge does this extremely annoying thing where you cannot use a file id independently, you have to include the project id with it.

This is also why the version calls have rather confusing parameters, because both are required (only for cf)

use async_trait::async_trait;
use ferinth::Ferinth;

pub type ID = String;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That took me quite a bit of time to find 🙃 lol

pub type ID = String;

#[derive(Debug, thiserror::Error)]
pub enum Error {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ModrinthError instead of Error ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After splitting into crates, it will namespaced as dotium_mr::Error which is the way I always do errors. I find that every other crate always uses Error with no modifications which is why I do that too.

))
}

async fn get_versions(&self, ids: Vec<(&ID, &ID)>) -> Result<Vec<Version<ID>>, Error> {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe explicit the type with something like:

pub struct VersionDescriptor(&ID, &ID)

along with a rustdoc to make the definition clearer

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup the rustdocs will explain this properly.

@Eskaan Eskaan changed the title Intial implementation Initial implementation Jun 26, 2022
@CLAassistant
Copy link

CLAassistant commented Jun 30, 2022

CLA assistant check
All committers have signed the CLA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

5 participants