use crate::client::Client;
use crate::error::{Error, Result};
use crate::file::File;
use crate::wire::*;
pub mod method {
pub const HELLO: u16 = 1;
pub const PING: u16 = 2;
pub const OPEN: u16 = 10;
pub const CLOSE: u16 = 11;
pub const READ: u16 = 12;
pub const WRITE: u16 = 13;
pub const READ_AT: u16 = 14;
pub const WRITE_AT: u16 = 15;
pub const SEEK: u16 = 16;
pub const FSYNC: u16 = 17;
pub const FLUSH: u16 = 18;
pub const FTRUNCATE: u16 = 19;
pub const STAT: u16 = 20;
pub const LSTAT: u16 = 21;
pub const FSTAT: u16 = 22;
pub const MKDIR: u16 = 23;
pub const RMDIR: u16 = 24;
pub const UNLINK: u16 = 25;
pub const RENAME: u16 = 26;
pub const SYMLINK: u16 = 27;
pub const READLINK: u16 = 28;
pub const LINK: u16 = 29;
pub const CHMOD: u16 = 30;
pub const UTIMENS: u16 = 31;
pub const TRUNCATE: u16 = 32;
pub const STATFS: u16 = 33;
pub const ACCESS: u16 = 34;
pub const OPENDIR: u16 = 40;
pub const READDIR: u16 = 41;
pub const CLOSEDIR: u16 = 42;
pub const LS: u16 = 43;
pub const STAT_BATCH: u16 = 50;
pub const READ_BATCH: u16 = 51;
pub const WRITE_BATCH: u16 = 52;
pub const READ_FILE: u16 = 53;
pub const WRITE_FILE: u16 = 54;
pub const REMOVE_ALL: u16 = 55;
pub const WATCH: u16 = 60;
pub const UNWATCH: u16 = 61;
pub const WARM_OPEN: u16 = 70;
pub const WARM_READ: u16 = 71;
pub const NOTICE: u16 = 62;
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct StatfsInfo {
pub block_size: u32,
pub blocks: u64,
pub blocks_free: u64,
pub blocks_avail: u64,
pub files: u64,
pub files_free: u64,
pub name_max: u32,
}
impl Client {
pub fn ping(&self) -> Result<()> {
self.unary::<Empty>(method::PING, &Empty {}).map(drop)
}
pub fn stat(&self, path: &str) -> Result<FileInfo> {
let r: StatResponse = self.unary(method::STAT, &StatRequest { path: path.into() })?;
r.info.ok_or_else(|| Error::Protocol("stat reply has no info".into()))
}
pub fn lstat(&self, path: &str) -> Result<FileInfo> {
let r: LstatResponse = self.unary(method::LSTAT, &LstatRequest { path: path.into() })?;
r.info.ok_or_else(|| Error::Protocol("lstat reply has no info".into()))
}
pub fn mkdir(&self, path: &str, mode: u32) -> Result<()> {
self
.unary::<Empty>(
method::MKDIR,
&MkdirRequest {
path: path.into(),
mode,
},
)
.map(drop)
}
pub fn rmdir(&self, path: &str) -> Result<()> {
self
.unary::<Empty>(method::RMDIR, &RmdirRequest { path: path.into() })
.map(drop)
}
pub fn unlink(&self, path: &str) -> Result<()> {
self
.unary::<Empty>(method::UNLINK, &UnlinkRequest { path: path.into() })
.map(drop)
}
pub fn rename(&self, from: &str, to: &str) -> Result<()> {
self
.unary::<Empty>(
method::RENAME,
&RenameRequest {
from: from.into(),
to: to.into(),
},
)
.map(drop)
}
pub fn symlink(&self, target: &str, link_path: &str) -> Result<()> {
self
.unary::<Empty>(
method::SYMLINK,
&SymlinkRequest {
target: target.into(),
link_path: link_path.into(),
},
)
.map(drop)
}
pub fn readlink(&self, path: &str) -> Result<String> {
let r: ReadlinkResponse = self.unary(method::READLINK, &ReadlinkRequest { path: path.into() })?;
Ok(r.target)
}
pub fn link(&self, existing: &str, new_path: &str) -> Result<()> {
self
.unary::<Empty>(
method::LINK,
&LinkRequest {
existing: existing.into(),
new_path: new_path.into(),
},
)
.map(drop)
}
pub fn chmod(&self, path: &str, mode: u32) -> Result<()> {
self
.unary::<Empty>(
method::CHMOD,
&ChmodRequest {
path: path.into(),
mode,
},
)
.map(drop)
}
pub fn truncate(&self, path: &str, size: i64) -> Result<()> {
self
.unary::<Empty>(
method::TRUNCATE,
&TruncateRequest {
path: path.into(),
size,
},
)
.map(drop)
}
pub fn statfs(&self, path: &str) -> Result<StatfsInfo> {
let r: StatfsResponse = self.unary(method::STATFS, &StatfsRequest { path: path.into() })?;
Ok(StatfsInfo {
block_size: r.block_size,
blocks: r.blocks,
blocks_free: r.blocks_free,
blocks_avail: r.blocks_avail,
files: r.files,
files_free: r.files_free,
name_max: r.name_max,
})
}
pub fn access(&self, path: &str, mode: u32) -> Result<()> {
self
.unary::<Empty>(
method::ACCESS,
&AccessRequest {
path: path.into(),
mode,
},
)
.map(drop)
}
pub fn remove_all(&self, path: &str) -> Result<u64> {
let r: RemoveAllResponse = self.unary(method::REMOVE_ALL, &RemoveAllRequest { path: path.into() })?;
Ok(r.removed)
}
pub fn warm_open(&self, path: &str) -> Result<u64> {
let r: WarmOpenResponse = self.unary(method::WARM_OPEN, &WarmOpenRequest { path: path.into() })?;
Ok(r.warm_id)
}
pub fn warm_read(&self, path: &str, offset: i64, length: i64) -> Result<u64> {
let r: WarmReadResponse = self.unary(
method::WARM_READ,
&WarmReadRequest {
path: path.into(),
offset,
length,
},
)?;
Ok(r.warm_id)
}
}
impl File {
pub fn flush(&self) -> Result<()> {
let st = self.state()?;
self
.unary::<Empty>(method::FLUSH, &FlushRequest { handle: st.handle })
.map(drop)
}
pub fn truncate(&self, size: i64) -> Result<()> {
let st = self.state()?;
self
.unary::<Empty>(
method::FTRUNCATE,
&FtruncateRequest {
handle: st.handle,
size,
},
)
.map(drop)
}
pub fn stat(&self) -> Result<FileInfo> {
let st = self.state()?;
let r: FstatResponse = self.unary(method::FSTAT, &FstatRequest { handle: st.handle })?;
r.info.ok_or_else(|| Error::Protocol("fstat reply has no info".into()))
}
}