use crate::helpers::{ColumnMapper, ColumnNameToId};
use crate::models::{Cell, CellValue, Contact, Hyperlink, ObjectType};
use crate::types::Result;
use serde_json::{json, to_value};
use std::io::{Error, ErrorKind};
pub struct CellFactory<'a> {
name_to_id: &'a ColumnNameToId<'a>,
}
impl<'a> CellFactory<'a> {
pub fn new(cols: &'a ColumnMapper) -> Self {
Self {
name_to_id: &cols.name_to_id,
}
}
pub fn cell<V: Into<CellValue>>(&'a self, column_name: &'a str, value: V) -> Result<Cell> {
match self.name_to_id.get(column_name) {
Some(&column_id) => Ok(self.cell_with_id(column_id, value)),
None => Err(Box::from(Error::new(
ErrorKind::NotFound,
format!(
"The column name `{}` does not exist in the sheet",
column_name
),
))),
}
}
pub fn cell_with_id<V: Into<CellValue>>(&'a self, column_id: u64, value: V) -> Cell {
Cell {
column_id,
value: Some(value.into()),
..Default::default()
}
}
pub fn url_hyperlink_cell(
&'a self,
column_name: &'a str,
display_text: &'a str,
url: &'a str,
) -> Result<Cell> {
match self.name_to_id.get(column_name) {
Some(&column_id) => Ok(self.url_hyperlink_cell_with_id(column_id, display_text, url)),
None => Err(Box::from(Error::new(
ErrorKind::NotFound,
format!(
"The column name `{}` does not exist in the sheet",
column_name
),
))),
}
}
pub fn url_hyperlink_cell_with_id(
&'a self,
column_id: u64,
display_text: &'a str,
url: &'a str,
) -> Cell {
Cell {
column_id,
value: Some(display_text.into()),
hyperlink: Some(Hyperlink::from(url)),
..Default::default()
}
}
pub fn multi_picklist_cell(&'a self, column_name: &'a str, values: &[&'a str]) -> Result<Cell> {
match self.name_to_id.get(column_name) {
Some(&column_id) => Ok(self.multi_picklist_cell_with_id(column_id, values)),
None => Err(Box::from(Error::new(
ErrorKind::NotFound,
format!(
"The column name `{}` does not exist in the sheet",
column_name
),
))),
}
}
pub fn multi_picklist_cell_with_id(&'a self, column_id: u64, values: &[&'a str]) -> Cell {
Cell {
column_id,
object_value: Some(json!(
{
"objectType": ObjectType::MultiPicklist.to_string(),
"values": values
})),
..Default::default()
}
}
pub fn contact_cell(
&'a self,
column_name: &'a str,
contact: impl Into<Contact<'a>>,
) -> Result<Cell> {
match self.name_to_id.get(column_name) {
Some(&column_id) => Ok(self.contact_cell_with_id(column_id, contact)),
None => Err(Box::from(Error::new(
ErrorKind::NotFound,
format!(
"The column name `{}` does not exist in the sheet",
column_name
),
))),
}
}
pub fn contact_cell_with_id(&'a self, column_id: u64, contact: impl Into<Contact<'a>>) -> Cell {
Cell {
column_id,
object_value: Some(to_value(contact.into()).unwrap()),
..Default::default()
}
}
pub fn multi_contact_cell(
&'a self,
column_name: &'a str,
contacts: &[Contact<'a>],
) -> Result<Cell> {
match self.name_to_id.get(column_name) {
Some(&column_id) => Ok(self.multi_contact_cell_with_id(column_id, contacts)),
None => Err(Box::from(Error::new(
ErrorKind::NotFound,
format!(
"The column name `{}` does not exist in the sheet",
column_name
),
))),
}
}
pub fn multi_contact_cell_with_id(
&'a self,
column_id: u64,
contacts: &[Contact<'a>],
) -> Cell {
let values = to_value(contacts).unwrap();
Cell {
column_id,
object_value: Some(json!(
{
"objectType": ObjectType::MultiContact.to_string(),
"values": values
})),
..Default::default()
}
}
}