aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHarald Eilertsen <haraldei@anduin.net>2021-07-05 22:03:47 +0200
committerHarald Eilertsen <haraldei@anduin.net>2021-07-05 22:03:47 +0200
commitd08138ea633da76d9ca390e4f9e3c5489aee23d1 (patch)
tree80a682350c75d6e01f05144cf054e9d48edbed07 /src
parent098adf3a6895529bbd467f13b55fc241099c2ff7 (diff)
downloadrust-zotapi-d08138ea633da76d9ca390e4f9e3c5489aee23d1.tar.gz
rust-zotapi-d08138ea633da76d9ca390e4f9e3c5489aee23d1.tar.bz2
rust-zotapi-d08138ea633da76d9ca390e4f9e3c5489aee23d1.zip
Update reqwest and make async.
This means adding the full tokio as a dependency. While there isn't much gain to going async in the current cli demo app, a full fledged app may have more to gain by it. First foray into async rust, so I might not do it right...
Diffstat (limited to 'src')
-rw-r--r--src/abconfig.rs4
-rw-r--r--src/abook.rs4
-rw-r--r--src/bin/zot/main.rs19
-rw-r--r--src/bin/zot/zot/abconfig.rs4
-rw-r--r--src/bin/zot/zot/abook.rs4
-rw-r--r--src/bin/zot/zot/channel_stream.rs4
-rw-r--r--src/bin/zot/zot/item.rs4
-rw-r--r--src/bin/zot/zot/network_stream.rs4
-rw-r--r--src/bin/zot/zot/xchan.rs8
-rw-r--r--src/channel_stream.rs4
-rw-r--r--src/client.rs40
-rw-r--r--src/group.rs8
-rw-r--r--src/item.rs21
-rw-r--r--src/network_stream.rs4
-rw-r--r--src/xchan.rs4
15 files changed, 77 insertions, 59 deletions
diff --git a/src/abconfig.rs b/src/abconfig.rs
index 6348030..ebb7e2b 100644
--- a/src/abconfig.rs
+++ b/src/abconfig.rs
@@ -61,14 +61,14 @@ impl ABConfigRequest {
self
}
- pub fn fetch(&self, client: &Client) -> Result<Vec<ABConfig>, Error> {
+ pub async fn fetch(&self, client: &Client) -> Result<Vec<ABConfig>, Error> {
let mut req = client.get("abconfig");
if let Some(id) = self.abook_id {
req = req.query(&[("abook_id", id.to_string())]);
}
- Ok(serde_json::from_str(&req.send()?.text()?)?)
+ Ok(serde_json::from_str(&req.send().await?.text().await?)?)
}
}
diff --git a/src/abook.rs b/src/abook.rs
index 59981ba..938a48f 100644
--- a/src/abook.rs
+++ b/src/abook.rs
@@ -114,13 +114,13 @@ impl AbookRequest {
self
}
- pub fn fetch(&self, client: &Client) -> Result<Vec<Abook>, Error> {
+ pub async fn fetch(&self, client: &Client) -> Result<Vec<Abook>, Error> {
let mut req = client.get("abook");
if let Some(id) = self.abook_id {
req = req.query(&[("abook_id", id.to_string())]);
}
- Ok(serde_json::from_str(&req.send()?.text()?)?)
+ Ok(serde_json::from_str(&req.send().await?.text().await?)?)
}
}
diff --git a/src/bin/zot/main.rs b/src/bin/zot/main.rs
index 5828f44..09fdd61 100644
--- a/src/bin/zot/main.rs
+++ b/src/bin/zot/main.rs
@@ -22,7 +22,8 @@ use std::str::FromStr;
mod zot;
-fn main() {
+#[tokio::main]
+async fn main() {
dotenv().ok();
let site = env::var("HZ_SITE").expect("SITE variable expected");
let user = env::var("HZ_USER").expect("USER variable expected");
@@ -79,24 +80,25 @@ fn main() {
match matches.subcommand() {
("channel", Some(m)) => {
let raw = m.is_present("raw");
- zot::channel_stream::fetch(&client, raw);
+ zot::channel_stream::fetch(&client, raw).await;
}
("network", Some(m)) => {
let raw = m.is_present("raw");
- zot::network_stream::fetch(&client, raw);
+ zot::network_stream::fetch(&client, raw).await;
}
("abconfig", _) => {
- zot::abconfig::fetch(&client);
+ zot::abconfig::fetch(&client).await;
}
("abook", Some(m)) => {
let raw = m.is_present("raw");
- zot::abook::fetch(&client, raw);
+ zot::abook::fetch(&client, raw).await;
}
("group", Some(m)) => {
if let Some(id) = m.value_of("ID") {
let res = zotapi::group_members()
.by_group_id(u64::from_str(id).unwrap())
.fetch(&client)
+ .await
.unwrap();
if m.is_present("raw") {
@@ -108,6 +110,7 @@ fn main() {
let res = zotapi::group_members()
.by_group_name(gname)
.fetch(&client)
+ .await
.unwrap();
if m.is_present("raw") {
@@ -116,7 +119,7 @@ fn main() {
zot::group::list_members(&res);
}
} else {
- let res = zotapi::group().fetch(&client).unwrap();
+ let res = zotapi::group().fetch(&client).await.unwrap();
if m.is_present("raw") {
println!("{}", res);
@@ -135,10 +138,10 @@ fn main() {
zot::xchan::Type::Addr
};
- zot::xchan::fetch(&client, raw, t, m.value_of("ID").unwrap());
+ zot::xchan::fetch(&client, raw, t, m.value_of("ID").unwrap()).await;
}
("post", Some(m)) => {
- zot::item::post(&client, m);
+ zot::item::post(&client, m).await;
}
_ => {
println!("{}", matches.usage());
diff --git a/src/bin/zot/zot/abconfig.rs b/src/bin/zot/zot/abconfig.rs
index 2e357e4..14875c8 100644
--- a/src/bin/zot/zot/abconfig.rs
+++ b/src/bin/zot/zot/abconfig.rs
@@ -17,8 +17,8 @@
use zotapi;
-pub fn fetch(client: &zotapi::Client) {
- match zotapi::ABConfig::z().fetch(&client) {
+pub async fn fetch(client: &zotapi::Client) {
+ match zotapi::ABConfig::z().fetch(&client).await {
Ok(v) => {
println!("Id: Chan: Cat: Key: Val: xchan:");
for entry in v {
diff --git a/src/bin/zot/zot/abook.rs b/src/bin/zot/zot/abook.rs
index 97025c3..6c33757 100644
--- a/src/bin/zot/zot/abook.rs
+++ b/src/bin/zot/zot/abook.rs
@@ -15,8 +15,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-pub fn fetch(client: &zotapi::Client, _raw: bool) {
- match zotapi::Abook::z().fetch(&client) {
+pub async fn fetch(client: &zotapi::Client, _raw: bool) {
+ match zotapi::Abook::z().fetch(&client).await {
Ok(abooks) => {
for b in abooks {
println!("{:?}", b);
diff --git a/src/bin/zot/zot/channel_stream.rs b/src/bin/zot/zot/channel_stream.rs
index 33ad7cf..68a5402 100644
--- a/src/bin/zot/zot/channel_stream.rs
+++ b/src/bin/zot/zot/channel_stream.rs
@@ -20,8 +20,8 @@ use zotapi;
use serde_json;
use std::iter::Iterator;
-pub fn fetch(client: &zotapi::Client, raw: bool) {
- match zotapi::channel_stream().fetch(&client) {
+pub async fn fetch(client: &zotapi::Client, raw: bool) {
+ match zotapi::channel_stream().fetch(&client).await {
Ok(payload) => {
if raw {
println!("{}", payload);
diff --git a/src/bin/zot/zot/item.rs b/src/bin/zot/zot/item.rs
index 648a9f0..dbb39ba 100644
--- a/src/bin/zot/zot/item.rs
+++ b/src/bin/zot/zot/item.rs
@@ -18,7 +18,7 @@
use clap::ArgMatches;
use zotapi;
-pub fn post(client: &zotapi::Client, args: &ArgMatches) {
+pub async fn post(client: &zotapi::Client, args: &ArgMatches<'_>) {
let mut msg = zotapi::item();
let body: String;
@@ -42,7 +42,7 @@ pub fn post(client: &zotapi::Client, args: &ArgMatches) {
}
}
- match msg.create(&client) {
+ match msg.create(&client).await {
Ok(res) => {
if res.success {
println!("New item with id {} posted successfully!", res.item_id);
diff --git a/src/bin/zot/zot/network_stream.rs b/src/bin/zot/zot/network_stream.rs
index 0e6edb4..a5a7142 100644
--- a/src/bin/zot/zot/network_stream.rs
+++ b/src/bin/zot/zot/network_stream.rs
@@ -20,8 +20,8 @@ use zotapi;
use serde_json;
use std::iter::Iterator;
-pub fn fetch(client: &zotapi::Client, raw: bool) {
- match zotapi::network_stream().fetch(&client) {
+pub async fn fetch(client: &zotapi::Client, raw: bool) {
+ match zotapi::network_stream().fetch(&client).await {
Ok(payload) => {
if raw {
println!("{}", payload);
diff --git a/src/bin/zot/zot/xchan.rs b/src/bin/zot/zot/xchan.rs
index 088d49c..146b2ab 100644
--- a/src/bin/zot/zot/xchan.rs
+++ b/src/bin/zot/zot/xchan.rs
@@ -23,11 +23,11 @@ pub enum Type {
GUID,
}
-pub fn fetch(client: &zotapi::Client, _raw: bool, t: Type, id: &str) {
+pub async fn fetch(client: &zotapi::Client, _raw: bool, t: Type, id: &str) {
let res = match t {
- Type::Addr => zotapi::XChan::z().by_address(&id).fetch(&client),
- Type::Hash => zotapi::XChan::z().by_hash(&id).fetch(&client),
- Type::GUID => zotapi::XChan::z().by_guid(&id).fetch(&client),
+ Type::Addr => zotapi::XChan::z().by_address(&id).fetch(&client).await,
+ Type::Hash => zotapi::XChan::z().by_hash(&id).fetch(&client).await,
+ Type::GUID => zotapi::XChan::z().by_guid(&id).fetch(&client).await,
};
match res {
diff --git a/src/channel_stream.rs b/src/channel_stream.rs
index 49f51e7..ed63f11 100644
--- a/src/channel_stream.rs
+++ b/src/channel_stream.rs
@@ -24,7 +24,7 @@ pub fn channel_stream() -> ChannelStream {
}
impl ChannelStream {
- pub fn fetch(&self, client: &Client) -> Result<String, Error> {
- client.fetch_stream("channel/stream", &())
+ pub async fn fetch(&self, client: &Client) -> Result<String, Error> {
+ client.fetch_stream("channel/stream", &()).await
}
}
diff --git a/src/client.rs b/src/client.rs
index c681b27..3f43479 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -22,6 +22,7 @@ use reqwest::{
};
use serde::Serialize;
use std::collections::BTreeMap;
+use std::fs::File;
use std::io::Read;
use url::Url;
@@ -56,22 +57,17 @@ impl Client {
r.to_string()
}
- pub fn fetch_stream<T>(&self, path: &str, args: &T) -> Result<String, Error>
+ pub async fn fetch_stream<T>(&self, path: &str, args: &T) -> Result<String, Error>
where
T: Serialize + std::fmt::Debug,
{
let url = dbg!(self.url(path, args));
- let res = self
- .inner
- .get(&url)
- .header(ACCEPT, "application/json")
- .basic_auth(self.user.clone(), Some(self.pw.clone()))
- .send()?;
+ let res = self.get(&url).send().await?;
- handle_result(res)
+ handle_result(res).await
}
- pub fn post_data<T>(&self, path: &str, data: &T) -> Result<String, Error>
+ pub async fn post_data<T>(&self, path: &str, data: &T) -> Result<String, Error>
where
T: Serialize + std::fmt::Debug,
{
@@ -84,12 +80,12 @@ impl Client {
.basic_auth(self.user.clone(), Some(self.pw.clone()))
.body(serde_qs::to_string(&data)?))
//.form(&data))
- .send()?;
+ .send().await?;
- handle_result(res)
+ handle_result(res).await
}
- pub fn post_multipart<T>(
+ pub async fn post_multipart<T>(
&self,
path: &str,
data: &BTreeMap<&str, T>,
@@ -106,7 +102,14 @@ impl Client {
}
for f in files.iter() {
- form = form.file("media", f).unwrap();
+ let mut pdata = vec![];
+ let path = std::path::Path::new(f);
+ File::open(path)?.read_to_end(&mut pdata)?;
+
+ let filename = String::from(path.file_name().unwrap().to_str().unwrap());
+ let p = reqwest::multipart::Part::bytes(pdata)
+ .file_name(filename);
+ form = form.part("media", p);
}
let res = self
@@ -114,9 +117,10 @@ impl Client {
.post(&url)
.basic_auth(self.user.clone(), Some(self.pw.clone()))
.multipart(form)
- .send()?;
+ .send()
+ .await?;
- handle_result(res)
+ handle_result(res).await
}
/// Return a RequestBuilder object that's set up with the correct
@@ -139,13 +143,11 @@ impl Client {
// A common function for handling the response after a request.
//
// Consumes the response, and return it as a string or an error.
-fn handle_result(mut res: reqwest::Response) -> Result<String, Error> {
+async fn handle_result(res: reqwest::Response) -> Result<String, Error> {
match res.status() {
StatusCode::UNAUTHORIZED => Err(Error::Unauthorized),
StatusCode::OK => {
- let mut body = String::new();
- res.read_to_string(&mut body)?;
- Ok(body)
+ Ok(res.text().await?)
}
_ => {
eprintln!("Received unknown status: {:?}", res.status());
diff --git a/src/group.rs b/src/group.rs
index 2ed8e92..cf3a057 100644
--- a/src/group.rs
+++ b/src/group.rs
@@ -24,8 +24,8 @@ pub fn group() -> Group {
}
impl Group {
- pub fn fetch(&self, client: &Client) -> Result<String, Error> {
- client.fetch_stream("group", &())
+ pub async fn fetch(&self, client: &Client) -> Result<String, Error> {
+ client.fetch_stream("group", &()).await
}
}
@@ -57,7 +57,7 @@ impl<'a> GroupMembers<'a> {
self
}
- pub fn fetch(&self, client: &Client) -> Result<String, Error> {
- client.fetch_stream("group_members", &self.id.as_ref().unwrap())
+ pub async fn fetch(&self, client: &Client) -> Result<String, Error> {
+ client.fetch_stream("group_members", &self.id.as_ref().unwrap()).await
}
}
diff --git a/src/item.rs b/src/item.rs
index 7c5935d..d61401b 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -21,6 +21,8 @@ use reqwest::{
};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
+use std::fs::File;
+use std::io::Read;
/// Data type for values that an Item can hold.
#[derive(Debug, Serialize)]
@@ -81,13 +83,17 @@ pub struct ItemCreatedResponse {
/// Typical usage:
///
/// ```no_run
+/// # async {
/// let client = zotapi::client("https://myhub.com", "mychannel", "mypw");
/// let new_post = zotapi::item()
/// .title("A title")
/// .body("The body of the post")
/// .file("/my/photo.jpg")
-/// .create(&client)?;
+/// .create(&client)
+/// .await?;
/// # Ok::<(), zotapi::Error>(())
+/// # };
+/// ```
/// ```
#[derive(Debug)]
pub struct ItemBuilder<'a> {
@@ -133,7 +139,7 @@ impl<'a> ItemBuilder<'a> {
}
/// Create the item by poting it to the server
- pub fn create(&self, client: &Client) -> Result<ItemCreatedResponse, Error> {
+ pub async fn create(&self, client: &Client) -> Result<ItemCreatedResponse, Error> {
dbg!(self);
let mut req = client.post("item/update");
@@ -149,13 +155,20 @@ impl<'a> ItemBuilder<'a> {
}
for f in self.files.iter() {
- form = form.file("media", f)?;
+ let mut pdata = vec![];
+ let path = std::path::Path::new(f);
+ File::open(path)?.read_to_end(&mut pdata)?;
+
+ let filename = String::from(path.file_name().unwrap().to_str().unwrap());
+ let p = reqwest::multipart::Part::bytes(pdata)
+ .file_name(filename);
+ form = form.part("media", p);
}
req = req.multipart(form)
}
- Ok(serde_json::from_str(&req.send()?.text()?)?)
+ Ok(serde_json::from_str(&req.send().await?.text().await?)?)
}
}
diff --git a/src/network_stream.rs b/src/network_stream.rs
index 8204458..80e7c11 100644
--- a/src/network_stream.rs
+++ b/src/network_stream.rs
@@ -24,7 +24,7 @@ pub fn network_stream() -> NetworkStream {
}
impl NetworkStream {
- pub fn fetch(&self, client: &Client) -> Result<String, Error> {
- client.fetch_stream("network/stream", &())
+ pub async fn fetch(&self, client: &Client) -> Result<String, Error> {
+ client.fetch_stream("network/stream", &()).await
}
}
diff --git a/src/xchan.rs b/src/xchan.rs
index 994f4b0..6fbe7a2 100644
--- a/src/xchan.rs
+++ b/src/xchan.rs
@@ -80,7 +80,7 @@ impl<'a> XChanRequest<'a> {
self
}
- pub fn fetch(&self, client: &Client) -> Result<XChan, Error> {
+ pub async fn fetch(&self, client: &Client) -> Result<XChan, Error> {
let mut req = client.get("xchan");
if let Some(sel) = &self.data {
@@ -91,6 +91,6 @@ impl<'a> XChanRequest<'a> {
};
}
- Ok(serde_json::from_str(&dbg!(req.send()?.text()?))?)
+ Ok(serde_json::from_str(&dbg!(req.send().await?.text().await?))?)
}
}