Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions lib/src/api/studies.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,91 @@
use futures::stream::StreamExt;

use crate::client::LichessApi;
use crate::error::Result;
use crate::model::studies::create::{CreateStudyForm, CreateStudyResponse};
use crate::model::studies::import_pgn_into_study::{PostRequest, StudyImportPgnChapters};
use crate::model::studies::*;

impl LichessApi<reqwest::Client> {
pub async fn create_study(&self, form: CreateStudyForm) -> Result<CreateStudyResponse> {
self.get_single_model(create::PostRequest::new(form)).await
}

pub async fn import_pgn_into_study(
&self,
request: impl Into<PostRequest>,
) -> Result<StudyImportPgnChapters> {
self.get_single_model(request.into()).await
}

pub async fn export_study_chapter_pgn(
&self,
study_id: &str,
chapter_id: &str,
query: export_chapter::GetQuery,
) -> Result<impl StreamExt<Item = Result<String>>> {
self.get_pgn(export_chapter::GetRequest::new(study_id, chapter_id, query))
.await
}

pub async fn export_study_pgn(
&self,
study_id: &str,
query: export_study::GetQuery,
) -> Result<impl StreamExt<Item = Result<String>>> {
self.get_pgn(export_study::GetRequest::new(study_id, query))
.await
}

pub async fn get_study_metadata(
&self,
request: impl Into<study_metadata::HeadRequest>,
) -> Result<()> {
self.get_empty(request.into()).await
}

pub async fn update_study_chapter_tags(
&self,
study_id: &str,
chapter_id: &str,
form: update_chapter_tags::UpdateChapterTagsForm,
) -> Result<()> {
self.get_empty(update_chapter_tags::PostRequest::new(
study_id, chapter_id, form,
))
.await
}

pub async fn update_study_chapter_moves(
&self,
study_id: &str,
chapter_id: &str,
form: update_chapter_moves::UpdateChapterMovesForm,
) -> Result<()> {
self.get_empty(update_chapter_moves::PostRequest::new(
study_id, chapter_id, form,
))
.await
}

pub async fn export_user_studies_pgn(
&self,
username: &str,
query: export_user_studies::GetQuery,
) -> Result<impl StreamExt<Item = Result<String>>> {
self.get_pgn(export_user_studies::GetRequest::new(username, query))
.await
}

pub async fn list_user_studies(
&self,
request: impl Into<list_user_studies::GetRequest>,
) -> Result<impl StreamExt<Item = Result<StudyMetadata>>> {
self.get_streamed_models(request.into()).await
}

pub async fn delete_study_chapter(&self, study_id: &str, chapter_id: &str) -> Result<()> {
self.get_empty(delete_chapter::DeleteRequest::new(study_id, chapter_id))
.await
}
}
8 changes: 8 additions & 0 deletions lib/src/model/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@ where
Self::create(path, query, None, domain, http::Method::GET)
}

pub(crate) fn head(
path: impl Into<String>,
query: impl Into<Option<Q>>,
domain: impl Into<Option<Domain>>,
) -> Self {
Self::create(path, query, None, domain, http::Method::HEAD)
}

pub(crate) fn post(
path: impl Into<String>,
query: impl Into<Option<Q>>,
Expand Down
52 changes: 52 additions & 0 deletions lib/src/model/studies/create.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use crate::model::{Body, Request};
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;

#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum Visibility {
Public,
Unlisted,
Private,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum StudyUserSelection {
Nobody,
Owner,
Contributor,
Member,
Everyone,
}

#[skip_serializing_none]
#[derive(Clone, Debug, Serialize)]
pub struct CreateStudyForm {
pub name: String,
pub visibility: Visibility,
pub flair: Option<String>,
pub computer: StudyUserSelection,
pub explorer: StudyUserSelection,
pub cloneable: StudyUserSelection,
pub shareable: StudyUserSelection,
pub chat: StudyUserSelection,
pub sticky: Option<bool>,
pub description: Option<bool>,
}

#[derive(Default, Clone, Debug, Deserialize, Serialize)]
pub struct CreateStudyResponse {
pub id: String,
}

#[derive(Default, Clone, Debug, Serialize)]
pub struct PostQuery;

pub type PostRequest = Request<PostQuery, CreateStudyForm>;

impl PostRequest {
pub fn new(form: CreateStudyForm) -> Self {
Self::post("/api/study", None, Body::Form(form), None)
}
}
18 changes: 18 additions & 0 deletions lib/src/model/studies/delete_chapter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use crate::model::Request;
use serde::Serialize;

#[derive(Default, Clone, Debug, Serialize)]
pub struct DeleteQuery;

pub type DeleteRequest = Request<DeleteQuery>;

impl DeleteRequest {
pub fn new(study_id: &str, chapter_id: &str) -> Self {
Self::delete(
format!("/api/study/{study_id}/{chapter_id}"),
None,
None,
None,
)
}
}
21 changes: 21 additions & 0 deletions lib/src/model/studies/export_chapter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use crate::model::Request;
use crate::model::studies::PgnExportQuery;
use serde::Serialize;

#[derive(Default, Clone, Debug, Serialize)]
pub struct GetQuery {
#[serde(flatten)]
pub options: PgnExportQuery,
}

pub type GetRequest = Request<GetQuery>;

impl GetRequest {
pub fn new(study_id: &str, chapter_id: &str, query: GetQuery) -> Self {
Self::get(
format!("/api/study/{study_id}/{chapter_id}.pgn"),
query,
None,
)
}
}
17 changes: 17 additions & 0 deletions lib/src/model/studies/export_study.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use crate::model::Request;
use crate::model::studies::PgnExportQuery;
use serde::Serialize;

#[derive(Default, Clone, Debug, Serialize)]
pub struct GetQuery {
#[serde(flatten)]
pub options: PgnExportQuery,
}

pub type GetRequest = Request<GetQuery>;

impl GetRequest {
pub fn new(study_id: &str, query: GetQuery) -> Self {
Self::get(format!("/api/study/{study_id}.pgn"), query, None)
}
}
17 changes: 17 additions & 0 deletions lib/src/model/studies/export_user_studies.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use crate::model::Request;
use crate::model::studies::PgnExportQuery;
use serde::Serialize;

#[derive(Default, Clone, Debug, Serialize)]
pub struct GetQuery {
#[serde(flatten)]
pub options: PgnExportQuery,
}

pub type GetRequest = Request<GetQuery>;

impl GetRequest {
pub fn new(username: &str, query: GetQuery) -> Self {
Self::get(format!("/api/study/by/{username}/export.pgn"), query, None)
}
}
19 changes: 19 additions & 0 deletions lib/src/model/studies/list_user_studies.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use crate::model::Request;
use serde::Serialize;

#[derive(Default, Clone, Debug, Serialize)]
pub struct GetQuery;

pub type GetRequest = Request<GetQuery>;

impl GetRequest {
pub fn new(username: &str) -> Self {
Self::get(format!("/api/study/by/{username}"), None, None)
}
}

impl<S: AsRef<str>> From<S> for GetRequest {
fn from(username: S) -> Self {
Self::new(username.as_ref())
}
}
30 changes: 30 additions & 0 deletions lib/src/model/studies/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,31 @@
pub mod create;
pub mod delete_chapter;
pub mod export_chapter;
pub mod export_study;
pub mod export_user_studies;
pub mod import_pgn_into_study;
pub mod list_user_studies;
pub mod study_metadata;
pub mod update_chapter_moves;
pub mod update_chapter_tags;

use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;

#[skip_serializing_none]
#[derive(Default, Clone, Debug, Serialize)]
pub struct PgnExportQuery {
pub clocks: Option<bool>,
pub comments: Option<bool>,
pub variations: Option<bool>,
pub orientation: Option<bool>,
}

#[derive(Default, Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct StudyMetadata {
pub id: String,
pub name: String,
pub created_at: i64,
pub updated_at: i64,
}
19 changes: 19 additions & 0 deletions lib/src/model/studies/study_metadata.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use crate::model::Request;
use serde::Serialize;

#[derive(Default, Clone, Debug, Serialize)]
pub struct HeadQuery;

pub type HeadRequest = Request<HeadQuery>;

impl HeadRequest {
pub fn new(study_id: &str) -> Self {
Self::head(format!("/api/study/{study_id}.pgn"), None, None)
}
}

impl<S: AsRef<str>> From<S> for HeadRequest {
fn from(study_id: S) -> Self {
Self::new(study_id.as_ref())
}
}
23 changes: 23 additions & 0 deletions lib/src/model/studies/update_chapter_moves.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use crate::model::{Body, Request};
use serde::Serialize;

#[derive(Default, Clone, Debug, Serialize)]
pub struct UpdateChapterMovesForm {
pub pgn: String,
}

#[derive(Default, Clone, Debug, Serialize)]
pub struct PostQuery;

pub type PostRequest = Request<PostQuery, UpdateChapterMovesForm>;

impl PostRequest {
pub fn new(study_id: &str, chapter_id: &str, form: UpdateChapterMovesForm) -> Self {
Self::post(
format!("/api/study/{study_id}/{chapter_id}/moves"),
None,
Body::Form(form),
None,
)
}
}
23 changes: 23 additions & 0 deletions lib/src/model/studies/update_chapter_tags.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use crate::model::{Body, Request};
use serde::Serialize;

#[derive(Default, Clone, Debug, Serialize)]
pub struct UpdateChapterTagsForm {
pub pgn: String,
}

#[derive(Default, Clone, Debug, Serialize)]
pub struct PostQuery;

pub type PostRequest = Request<PostQuery, UpdateChapterTagsForm>;

impl PostRequest {
pub fn new(study_id: &str, chapter_id: &str, form: UpdateChapterTagsForm) -> Self {
Self::post(
format!("/api/study/{study_id}/{chapter_id}/tags"),
None,
Body::Form(form),
None,
)
}
}
1 change: 1 addition & 0 deletions lib/tests/data/response/study_create.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "id": "9kze56XR" }
1 change: 1 addition & 0 deletions lib/tests/data/response/study_metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "id": "WTvnkWAL", "name": "Guess the move", "createdAt": 1463756350225, "updatedAt": 1469965025205 }
6 changes: 6 additions & 0 deletions lib/tests/offline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ pub fn swiss_tournaments() {
test_response_model::<swiss_tournaments::SwissResult>("swiss_result");
}

#[test]
pub fn studies() {
test_response_model::<studies::create::CreateStudyResponse>("study_create");
test_response_model::<studies::StudyMetadata>("study_metadata");
}

fn test_response_model<Model: Serialize + DeserializeOwned>(file_name: &str) {
let path = format!("./tests/data/response/{}.json", file_name);
test_model::<Model>(path);
Expand Down
Loading