mwapi/
lib.rs

1/*
2Copyright (C) 2021 Kunal Mehta <legoktm@debian.org>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 3 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program.  If not, see <https://www.gnu.org/licenses/>.
16 */
17
18//! A MediaWiki API client library.
19//!
20//! `mwapi` is a low-level library for the [MediaWiki Action API](https://www.mediawiki.org/wiki/API:Main_page).
21//! If you intend to edit pages or want a higher-level interface, it's recommended to use [`mwbot`](https://docs.rs/mwbot/),
22//! which builds on top of this crate.
23//!
24//! ## Goals
25//! * generic to fit any application, whether for interactive usage
26//!   or writing a bot
27//! * fully compatible with concurrent use cases
28//! * turns MediaWiki errors into Rust errors for you
29//! * logging (using the `tracing` crate) for visiblity into errors
30//! * follow all [best practices](https://www.mediawiki.org/wiki/API:Etiquette)
31//!
32//! ## Quick start
33//! ```
34//! # #[tokio::main]
35//! # async fn main() -> mwapi::Result<()> {
36//! let client = mwapi::Client::builder("https://en.wikipedia.org/w/api.php")
37//!     .set_user_agent("mwapi demo")
38//!     // Provide credentials for login:
39//!     // .set_botpassword("username", "password")
40//!     .build().await?;
41//! let resp = client.get_value(&[
42//!     ("action", "query"),
43//!     ("prop", "info"),
44//!     ("titles", "Taylor Swift"),
45//! ]).await?;
46//! let info = resp["query"]["pages"][0].clone();
47//! assert_eq!(info["ns"].as_u64().unwrap(), 0);
48//! assert_eq!(info["title"].as_str().unwrap(), "Taylor Swift");
49//! # Ok(())
50//! # }
51//!
52//! ```
53//!
54//! ## Functionality
55//! * authentication, using [OAuth2](https://www.mediawiki.org/wiki/OAuth/Owner-only_consumers#OAuth_2) (recommended) or BotPasswords
56//! * error handling, transforming MediaWiki errors into Rust ones
57//! * CSRF [token](https://www.mediawiki.org/wiki/API:Tokens) handling with `post_with_token`
58//! * rate limiting and concurrency controls
59//! * file uploads (needs `upload` feature)
60//!
61//! ## See also
62//! * [`mwbot`](https://docs.rs/mwbot/) provides a higher level interface to
63//!   interacting with MediaWiki
64//! * [`mwapi_responses`](https://docs.rs/mwapi_responses/) is a macro to
65//!   generate strict types for dynamic API queries
66//!
67//! ## Contributing
68//! `mwapi` is a part of the [`mwbot-rs` project](https://www.mediawiki.org/wiki/Mwbot-rs).
69//! We're always looking for new contributors, please [reach out](https://www.mediawiki.org/wiki/Mwbot-rs#Contributing)
70//! if you're interested!
71#![deny(clippy::all)]
72#![deny(rustdoc::all)]
73#![cfg_attr(docsrs, feature(doc_cfg))]
74
75mod client;
76mod error;
77mod params;
78mod responses;
79mod time;
80mod tokens;
81#[cfg(feature = "upload")]
82mod upload;
83
84const VERSION: &str = env!("CARGO_PKG_VERSION");
85
86pub use client::{Builder, Client, HttpClientProvider};
87pub use error::{ApiError, Error};
88pub use params::Params;
89use std::fmt::{Display, Formatter};
90
91pub type Result<T> = std::result::Result<T, Error>;
92
93/// Assert that your account has the specified login state, see
94/// [API:Assert](https://www.mediawiki.org/wiki/API:Assert) for more details.
95#[derive(Copy, Clone, Debug, Eq, PartialEq)]
96pub enum Assert {
97    /// Not logged in, aka anonymous
98    Anonymous,
99    /// Logged in to a bot account
100    Bot,
101    /// Logged in (to any account)
102    User,
103    /// Do not add any assert
104    None,
105}
106
107impl Assert {
108    fn value(&self) -> Option<&'static str> {
109        match self {
110            Assert::Anonymous => Some("anon"),
111            Assert::Bot => Some("bot"),
112            Assert::User => Some("user"),
113            Assert::None => None,
114        }
115    }
116}
117
118impl Default for Assert {
119    fn default() -> Self {
120        Self::None
121    }
122}
123
124#[derive(Clone, Copy, Debug)]
125pub enum ErrorFormat {
126    Html,
127    Wikitext,
128    Plaintext,
129}
130
131impl Display for ErrorFormat {
132    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
133        let val = match &self {
134            ErrorFormat::Html => "html",
135            ErrorFormat::Wikitext => "wikitext",
136            ErrorFormat::Plaintext => "plaintext",
137        };
138        write!(f, "{val}")
139    }
140}
141
142impl Default for ErrorFormat {
143    fn default() -> Self {
144        Self::Plaintext
145    }
146}
147
148#[derive(Debug, Copy, Clone, Eq, PartialEq)]
149pub(crate) enum Method {
150    Get,
151    Post,
152}