use std::collections::HashMap;
use super::{SapTableHeader, SapTableRow, cell::SapTableCell};
use crate::element::ElementWrapper;
use crate::element::definition::ElementDefinition as _;
use crate::element::parser::ElementParser;
use crate::error::{ElementError, WebDynproError};
pub trait FromSapTable<'body>: Sized {
fn from_table(
header: Option<&'body SapTableHeader>,
row: &'body SapTableRow,
parser: &'body ElementParser,
) -> Result<Self, WebDynproError>;
}
impl<'body> FromSapTable<'body> for Vec<Option<String>> {
fn from_table(
_header: Option<&'body SapTableHeader>,
row: &'body SapTableRow,
parser: &'body ElementParser,
) -> Result<Self, WebDynproError> {
let iter = row.iter_value(parser);
let vec = iter
.map(|val| match val {
Ok(cell) => match cell.content() {
Some(wrapper) => {
Ok(ElementWrapper::from_def(&wrapper, parser)?.try_into().ok())
}
None => Ok(None),
},
Err(err) => Err(err),
})
.collect::<Result<Vec<Option<String>>, WebDynproError>>()?;
Ok(vec)
}
}
impl<'body> FromSapTable<'body> for Vec<String> {
fn from_table(
_header: Option<&'body SapTableHeader>,
row: &'body SapTableRow,
parser: &'body ElementParser,
) -> Result<Self, WebDynproError> {
let iter = row.iter_value(parser);
iter.map(|val| match val {
Ok(cell) => match cell.content() {
Some(wrapper) => Ok(ElementWrapper::from_def(&wrapper, parser)?.try_into()?),
None => Err(ElementError::NoSuchContent {
element: "Cell Content".to_string(),
content: "No content provided".to_string(),
})?,
},
Err(err) => Err(err),
})
.collect::<Result<Vec<String>, WebDynproError>>()
}
}
impl<'body> FromSapTable<'body> for Vec<(String, Option<String>)> {
fn from_table(
header: Option<&'body SapTableHeader>,
row: &'body SapTableRow,
parser: &'body ElementParser,
) -> Result<Self, WebDynproError> {
let header = header.ok_or(ElementError::NoSuchContent {
element: row.table_def().id().to_string(),
content: "Header of table".to_string(),
})?;
let header_iter = header.iter_value(parser);
let header_string = header_iter
.map(|val| match val {
Ok(cell) => match cell.content() {
Some(wrapper) => Ok(ElementWrapper::from_def(&wrapper, parser)?.try_into()?),
None => Ok(cell.id().to_owned()),
},
Err(err) => Err(err),
})
.collect::<Result<Vec<String>, WebDynproError>>()?;
let iter = row.iter_value(parser);
let row_string = iter
.map(|val| match val {
Ok(cell) => match cell.content() {
Some(wrapper) => {
Ok(ElementWrapper::from_def(&wrapper, parser)?.try_into().ok())
}
None => Ok(None),
},
Err(err) => Err(err),
})
.collect::<Result<Vec<Option<String>>, WebDynproError>>()?;
let zip = header_string
.into_iter()
.zip(row_string)
.collect::<Vec<(String, Option<String>)>>();
Ok(zip)
}
}
impl<'body> FromSapTable<'body> for Vec<(String, String)> {
fn from_table(
header: Option<&'body SapTableHeader>,
row: &'body SapTableRow,
parser: &'body ElementParser,
) -> Result<Self, WebDynproError> {
let header = header.ok_or(ElementError::NoSuchContent {
element: row.table_def().id().to_string(),
content: "Header of table".to_string(),
})?;
let header_iter = header.iter_value(parser);
let header_string = header_iter
.map(|val| match val {
Ok(cell) => match cell.content() {
Some(wrapper) => Ok(ElementWrapper::from_def(&wrapper, parser)?.try_into()?),
None => Ok(cell.id().to_owned()),
},
Err(err) => Err(err),
})
.collect::<Result<Vec<String>, WebDynproError>>()?;
let iter = row.iter_value(parser);
let row_string = iter
.map(|val| match val {
Ok(cell) => match cell.content() {
Some(wrapper) => Ok(ElementWrapper::from_def(&wrapper, parser)?
.try_into()
.unwrap_or(wrapper.id().to_string())),
None => Ok("".to_owned()),
},
Err(err) => Err(err),
})
.collect::<Result<Vec<String>, WebDynproError>>()?;
let zip = header_string
.into_iter()
.zip(row_string)
.collect::<Vec<(String, String)>>();
Ok(zip)
}
}
impl<'body> FromSapTable<'body> for HashMap<String, String> {
fn from_table(
header: Option<&'body SapTableHeader>,
row: &'body SapTableRow,
parser: &'body ElementParser,
) -> Result<Self, WebDynproError> {
let vec = row.try_row_into::<Vec<(String, String)>>(header, parser)?;
Ok(vec.into_iter().collect())
}
}
impl<'body> FromSapTable<'body> for HashMap<String, Option<String>> {
fn from_table(
header: Option<&'body SapTableHeader>,
row: &'body SapTableRow,
parser: &'body ElementParser,
) -> Result<Self, WebDynproError> {
let vec = row.try_row_into::<Vec<(String, Option<String>)>>(header, parser)?;
Ok(vec.into_iter().collect())
}
}