use crate::{
domain::policy::pure::topology::IndexPolicyInput,
dto::{
page::Page,
topology::{AppIndexArgs, IndexEntryInput, IndexEntryResponse, SubnetIndexArgs},
},
storage::stable::index::{IndexEntryRecord, app::AppIndexData, subnet::SubnetIndexData},
view::topology::IndexEntryView,
};
fn data_entries_to_input(entries: Vec<IndexEntryRecord>) -> Vec<IndexEntryInput> {
entries
.into_iter()
.map(|entry| IndexEntryInput {
role: entry.role,
pid: entry.pid,
})
.collect()
}
fn input_entries_to_data(entries: Vec<IndexEntryInput>) -> Vec<IndexEntryRecord> {
entries
.into_iter()
.map(|entry| IndexEntryRecord {
role: entry.role,
pid: entry.pid,
})
.collect()
}
pub struct AppIndexDataMapper;
impl AppIndexDataMapper {
#[must_use]
pub fn data_to_input(data: AppIndexData) -> AppIndexArgs {
AppIndexArgs(data_entries_to_input(data.entries))
}
#[must_use]
pub fn input_to_data(input: AppIndexArgs) -> AppIndexData {
AppIndexData {
entries: input_entries_to_data(input.0),
}
}
}
pub struct SubnetIndexDataMapper;
impl SubnetIndexDataMapper {
#[must_use]
pub fn data_to_input(data: SubnetIndexData) -> SubnetIndexArgs {
SubnetIndexArgs(data_entries_to_input(data.entries))
}
#[must_use]
pub fn input_to_data(input: SubnetIndexArgs) -> SubnetIndexData {
SubnetIndexData {
entries: input_entries_to_data(input.0),
}
}
}
pub struct IndexEntryMapper;
impl IndexEntryMapper {
#[must_use]
pub fn records_to_projections(entries: Vec<IndexEntryRecord>) -> Vec<IndexEntryView> {
entries
.into_iter()
.map(|entry| IndexEntryView {
role: entry.role,
pid: entry.pid,
})
.collect()
}
#[must_use]
pub fn projection_page_to_response(page: Page<IndexEntryView>) -> Page<IndexEntryResponse> {
Page {
entries: page
.entries
.into_iter()
.map(|entry| IndexEntryResponse {
role: entry.role,
pid: entry.pid,
})
.collect(),
total: page.total,
}
}
#[must_use]
pub fn records_to_policy_input(entries: &[IndexEntryRecord]) -> Vec<IndexPolicyInput> {
entries
.iter()
.map(|entry| IndexPolicyInput {
role: entry.role.clone(),
pid: entry.pid,
})
.collect()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{cdk::types::Principal, ids::CanisterRole};
#[test]
fn records_project_before_response_mapping() {
let pid = Principal::from_slice(&[1]);
let projections = IndexEntryMapper::records_to_projections(vec![IndexEntryRecord {
role: CanisterRole::new("app"),
pid,
}]);
let response = IndexEntryMapper::projection_page_to_response(Page {
entries: projections,
total: 1,
});
assert_eq!(response.total, 1);
assert_eq!(response.entries.len(), 1);
assert_eq!(response.entries[0].role, CanisterRole::new("app"));
assert_eq!(response.entries[0].pid, pid);
}
}