mirror of
https://github.com/soywod/himalaya.git
synced 2025-04-19 07:43:39 +00:00
add mailbox attributes (#134)
This commit is contained in:
parent
435932a501
commit
dcbbe01c94
4 changed files with 107 additions and 28 deletions
|
@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Mailbox attributes [#134]
|
||||
|
||||
### Changed
|
||||
|
||||
- Get signature from file [#135]
|
||||
|
@ -243,6 +247,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
[#131]: https://github.com/soywod/himalaya/issues/131
|
||||
[#132]: https://github.com/soywod/himalaya/issues/132
|
||||
[#133]: https://github.com/soywod/himalaya/issues/133
|
||||
[#134]: https://github.com/soywod/himalaya/issues/134
|
||||
[#135]: https://github.com/soywod/himalaya/issues/135
|
||||
[#136]: https://github.com/soywod/himalaya/issues/136
|
||||
[#138]: https://github.com/soywod/himalaya/issues/138
|
||||
|
|
|
@ -7,7 +7,6 @@ use std::{collections::HashSet, iter::FromIterator, net::TcpStream};
|
|||
use crate::{
|
||||
config::model::{Account, Config},
|
||||
flag::model::Flag,
|
||||
mbox::model::{Mbox, Mboxes},
|
||||
msg::model::Msg,
|
||||
};
|
||||
|
||||
|
@ -167,16 +166,13 @@ impl<'ic> ImapConnector<'ic> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn list_mboxes(&mut self) -> Result<Mboxes> {
|
||||
let mboxes = self
|
||||
pub fn list_mboxes(&mut self) -> Result<imap::types::ZeroCopy<Vec<imap::types::Name>>> {
|
||||
let names = self
|
||||
.sess
|
||||
.list(Some(""), Some("*"))
|
||||
.chain_err(|| "Cannot list mailboxes")?
|
||||
.iter()
|
||||
.map(Mbox::from_name)
|
||||
.collect::<Vec<_>>();
|
||||
.chain_err(|| "Cannot list mailboxes")?;
|
||||
|
||||
Ok(Mboxes(mboxes))
|
||||
Ok(names)
|
||||
}
|
||||
|
||||
pub fn list_msgs(
|
||||
|
|
|
@ -2,7 +2,7 @@ use clap;
|
|||
use error_chain::error_chain;
|
||||
use log::{debug, trace};
|
||||
|
||||
use crate::{app::App, imap::model::ImapConnector};
|
||||
use crate::{app::App, imap::model::ImapConnector, mbox::model::Mboxes};
|
||||
|
||||
error_chain! {
|
||||
links {
|
||||
|
@ -36,7 +36,8 @@ pub fn mbox_matches(app: &App) -> Result<bool> {
|
|||
debug!("mailboxes command matched");
|
||||
|
||||
let mut imap_conn = ImapConnector::new(&app.account)?;
|
||||
let mboxes = imap_conn.list_mboxes()?;
|
||||
let names = imap_conn.list_mboxes()?;
|
||||
let mboxes = Mboxes::from(&names);
|
||||
debug!("found {} mailboxes", mboxes.0.len());
|
||||
trace!("mailboxes: {:?}", mboxes);
|
||||
app.output.print(mboxes);
|
||||
|
|
|
@ -1,29 +1,100 @@
|
|||
use imap;
|
||||
use serde::Serialize;
|
||||
use serde::{
|
||||
ser::{self, SerializeSeq},
|
||||
Serialize,
|
||||
};
|
||||
use std::fmt;
|
||||
|
||||
use crate::table::{Cell, Row, Table};
|
||||
|
||||
// Mbox
|
||||
// Attribute
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct Mbox {
|
||||
pub delim: String,
|
||||
pub name: String,
|
||||
pub attributes: Vec<String>,
|
||||
}
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct SerializableAttribute<'a>(&'a imap::types::NameAttribute<'a>);
|
||||
|
||||
impl Mbox {
|
||||
pub fn from_name(name: &imap::types::Name) -> Self {
|
||||
Self {
|
||||
delim: name.delimiter().unwrap_or_default().to_owned(),
|
||||
name: name.name().to_owned(),
|
||||
attributes: vec![], // TODO: set attributes
|
||||
impl<'a> Into<&'a str> for &'a SerializableAttribute<'a> {
|
||||
fn into(self) -> &'a str {
|
||||
match &self.0 {
|
||||
imap::types::NameAttribute::NoInferiors => "\\NoInferiors",
|
||||
imap::types::NameAttribute::NoSelect => "\\NoSelect",
|
||||
imap::types::NameAttribute::Marked => "\\Marked",
|
||||
imap::types::NameAttribute::Unmarked => "\\Unmarked",
|
||||
imap::types::NameAttribute::Custom(cow) => cow,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Table for Mbox {
|
||||
impl<'a> ser::Serialize for SerializableAttribute<'a> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: ser::Serializer,
|
||||
{
|
||||
serializer.serialize_str(self.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Attributes<'a>(&'a [imap::types::NameAttribute<'a>]);
|
||||
|
||||
impl<'a> From<&'a [imap::types::NameAttribute<'a>]> for Attributes<'a> {
|
||||
fn from(attrs: &'a [imap::types::NameAttribute<'a>]) -> Self {
|
||||
Self(attrs)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ToString for Attributes<'a> {
|
||||
fn to_string(&self) -> String {
|
||||
match self.0.len() {
|
||||
0 => String::new(),
|
||||
1 => {
|
||||
let attr = &SerializableAttribute(&self.0[0]);
|
||||
let attr: &str = attr.into();
|
||||
attr.to_owned()
|
||||
}
|
||||
_ => {
|
||||
let attr = &SerializableAttribute(&self.0[0]);
|
||||
let attr: &str = attr.into();
|
||||
format!("{}, {}", attr, Attributes(&self.0[1..]).to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ser::Serialize for Attributes<'a> {
|
||||
fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error>
|
||||
where
|
||||
T: ser::Serializer,
|
||||
{
|
||||
let mut seq = serializer.serialize_seq(Some(self.0.len()))?;
|
||||
|
||||
for attr in self.0 {
|
||||
seq.serialize_element(&SerializableAttribute(attr))?;
|
||||
}
|
||||
|
||||
seq.end()
|
||||
}
|
||||
}
|
||||
|
||||
// Mailbox
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct Mbox<'a> {
|
||||
pub delim: String,
|
||||
pub name: String,
|
||||
pub attributes: Attributes<'a>,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a imap::types::Name> for Mbox<'a> {
|
||||
fn from(name: &'a imap::types::Name) -> Self {
|
||||
Self {
|
||||
delim: name.delimiter().unwrap_or_default().to_owned(),
|
||||
name: name.name().to_owned(),
|
||||
attributes: Attributes::from(name.attributes()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Table for Mbox<'a> {
|
||||
fn head() -> Row {
|
||||
Row::new()
|
||||
.cell(Cell::new("DELIM").bold().underline().white())
|
||||
|
@ -41,16 +112,22 @@ impl Table for Mbox {
|
|||
Row::new()
|
||||
.cell(Cell::new(&self.delim).white())
|
||||
.cell(Cell::new(&self.name).green())
|
||||
.cell(Cell::new(&self.attributes.join(", ")).shrinkable().yellow())
|
||||
.cell(Cell::new(&self.attributes.to_string()).shrinkable().blue())
|
||||
}
|
||||
}
|
||||
|
||||
// Mboxes
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct Mboxes(pub Vec<Mbox>);
|
||||
pub struct Mboxes<'a>(pub Vec<Mbox<'a>>);
|
||||
|
||||
impl fmt::Display for Mboxes {
|
||||
impl<'a> From<&'a imap::types::ZeroCopy<Vec<imap::types::Name>>> for Mboxes<'a> {
|
||||
fn from(names: &'a imap::types::ZeroCopy<Vec<imap::types::Name>>) -> Self {
|
||||
Self(names.iter().map(Mbox::from).collect::<Vec<_>>())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Mboxes<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
writeln!(f, "\n{}", Table::render(&self.0))
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue