Skip to main content

lichess_api/api/
studies.rs

1//! Create, import into, and export [studies](https://lichess.org/study) and
2//! their chapters.
3//!
4//! Studies can be exported as PGN, either a single chapter, a whole study, or
5//! every study belonging to a user; [`update_study_chapter_moves`] and
6//! [`update_study_chapter_tags`] edit an existing chapter's move tree and PGN
7//! tags in place. See [`model::studies`] for the request/response types.
8//!
9//! Reading a study you don't own only returns it if it's public. Pass a
10//! bearer token to also see your own private and unlisted studies; writes
11//! (creating, importing, deleting, or editing a chapter) always require one.
12//!
13//! [`update_study_chapter_moves`]: LichessApi::update_study_chapter_moves
14//! [`update_study_chapter_tags`]: LichessApi::update_study_chapter_tags
15//! [`model::studies`]: crate::model::studies
16
17use futures::stream::StreamExt;
18
19use crate::client::LichessApi;
20use crate::error::Result;
21use crate::model::studies::create::{CreateStudyForm, CreateStudyResponse};
22use crate::model::studies::import_pgn_into_study::{PostRequest, StudyImportPgnChapters};
23use crate::model::studies::*;
24
25impl LichessApi<reqwest::Client> {
26    pub async fn create_study(&self, form: CreateStudyForm) -> Result<CreateStudyResponse> {
27        self.get_single_model(create::PostRequest::new(form)).await
28    }
29
30    pub async fn import_pgn_into_study(
31        &self,
32        request: impl Into<PostRequest>,
33    ) -> Result<StudyImportPgnChapters> {
34        self.get_single_model(request.into()).await
35    }
36
37    pub async fn export_study_chapter_pgn(
38        &self,
39        study_id: &str,
40        chapter_id: &str,
41        query: export_chapter::GetQuery,
42    ) -> Result<impl StreamExt<Item = Result<String>>> {
43        self.get_pgn(export_chapter::GetRequest::new(study_id, chapter_id, query))
44            .await
45    }
46
47    pub async fn export_study_pgn(
48        &self,
49        study_id: &str,
50        query: export_study::GetQuery,
51    ) -> Result<impl StreamExt<Item = Result<String>>> {
52        self.get_pgn(export_study::GetRequest::new(study_id, query))
53            .await
54    }
55
56    pub async fn get_study_metadata(
57        &self,
58        request: impl Into<study_metadata::HeadRequest>,
59    ) -> Result<()> {
60        self.get_empty(request.into()).await
61    }
62
63    pub async fn update_study_chapter_tags(
64        &self,
65        study_id: &str,
66        chapter_id: &str,
67        form: update_chapter_tags::UpdateChapterTagsForm,
68    ) -> Result<()> {
69        self.get_empty(update_chapter_tags::PostRequest::new(
70            study_id, chapter_id, form,
71        ))
72        .await
73    }
74
75    pub async fn update_study_chapter_moves(
76        &self,
77        study_id: &str,
78        chapter_id: &str,
79        form: update_chapter_moves::UpdateChapterMovesForm,
80    ) -> Result<()> {
81        self.get_empty(update_chapter_moves::PostRequest::new(
82            study_id, chapter_id, form,
83        ))
84        .await
85    }
86
87    pub async fn export_user_studies_pgn(
88        &self,
89        username: &str,
90        query: export_user_studies::GetQuery,
91    ) -> Result<impl StreamExt<Item = Result<String>>> {
92        self.get_pgn(export_user_studies::GetRequest::new(username, query))
93            .await
94    }
95
96    pub async fn list_user_studies(
97        &self,
98        request: impl Into<list_user_studies::GetRequest>,
99    ) -> Result<impl StreamExt<Item = Result<StudyMetadata>>> {
100        self.get_streamed_models(request.into()).await
101    }
102
103    pub async fn delete_study_chapter(&self, study_id: &str, chapter_id: &str) -> Result<()> {
104        self.get_empty(delete_chapter::DeleteRequest::new(study_id, chapter_id))
105            .await
106    }
107}