arch_pkg_db/text/single/
parse.rs

1use super::TextCollection;
2use crate::{QueryDatabase, Text, single::InsertError};
3use arch_pkg_text::desc::{Query, QueryMut, misc::ShouldReuse};
4use derive_more::{Display, Error};
5use pipe_trait::Pipe;
6use rayon::prelude::*;
7
8/// Error type when trying to create a [`QueryDatabase`] from a [`TextCollection`].
9#[derive(Debug, Display, Clone, Copy, Error)]
10#[display(bound(ParseError: Display))]
11pub enum TextCollectionParseError<ParseError> {
12    Parse(ParseError),
13    Insert(InsertError),
14}
15
16/// Return type of [`TextCollection::parse`] and [`TextCollection::parse_mut`].
17type ParseResult<'a, Querier> = Result<
18    QueryDatabase<'a, Querier>,
19    TextCollectionParseError<<&'a str as TryInto<Querier>>::Error>,
20>;
21
22impl TextCollection {
23    /// Parse a database of queriers.
24    fn parse_with<'a, Querier, Insert, InsertSuccess>(
25        &'a self,
26        mut insert: Insert,
27    ) -> ParseResult<'a, Querier>
28    where
29        &'a str: TryInto<Querier>,
30        Insert:
31            FnMut(&mut QueryDatabase<'a, Querier>, Querier) -> Result<InsertSuccess, InsertError>,
32    {
33        let mut db = QueryDatabase::with_capacity(self.internal.len());
34
35        for text in &self.internal {
36            let querier = text
37                .as_str()
38                .try_into()
39                .map_err(TextCollectionParseError::Parse)?;
40            insert(&mut db, querier).map_err(TextCollectionParseError::Insert)?;
41        }
42
43        Ok(db)
44    }
45
46    /// Parse a database of [immutable queriers](Query).
47    pub fn parse<'a, Querier>(&'a self) -> ParseResult<'a, Querier>
48    where
49        &'a str: TryInto<Querier>,
50        Querier: Query<'a> + ShouldReuse,
51    {
52        self.parse_with(QueryDatabase::insert)
53    }
54
55    /// Parse a database of [mutable queriers](QueryMut).
56    pub fn parse_mut<'a, Querier>(&'a self) -> ParseResult<'a, Querier>
57    where
58        &'a str: TryInto<Querier>,
59        Querier: QueryMut<'a> + ShouldReuse,
60    {
61        self.parse_with(QueryDatabase::insert_mut)
62    }
63
64    /// Parse a database of queriers in parallel.
65    fn par_parse_with<'a, Querier, QueriersIntoDb>(
66        &'a self,
67        queriers_into_db: QueriersIntoDb,
68    ) -> ParseResult<'a, Querier>
69    where
70        &'a str: TryInto<Querier, Error: Send>,
71        Querier: Send,
72        QueriersIntoDb: FnOnce(Vec<Querier>) -> Result<QueryDatabase<'a, Querier>, InsertError>,
73    {
74        self.internal
75            .par_iter()
76            .map(Text::as_str)
77            .map(TryInto::<Querier>::try_into)
78            .collect::<Result<Vec<_>, _>>()
79            .map_err(TextCollectionParseError::Parse)?
80            .pipe(queriers_into_db)
81            .map_err(TextCollectionParseError::Insert)
82    }
83
84    /// Parse a database of [immutable queriers](Query) in parallel.
85    pub fn par_parse<'a, Querier>(&'a self) -> ParseResult<'a, Querier>
86    where
87        &'a str: TryInto<Querier, Error: Send>,
88        Querier: Query<'a> + ShouldReuse + Send,
89    {
90        self.par_parse_with(QueryDatabase::from_queriers)
91    }
92
93    /// Parse a database of [mutable queriers](QueryMut) in parallel.
94    pub fn par_parse_mut<'a, Querier>(&'a self) -> ParseResult<'a, Querier>
95    where
96        &'a str: TryInto<Querier, Error: Send>,
97        Querier: QueryMut<'a> + ShouldReuse + Send,
98    {
99        self.par_parse_with(QueryDatabase::from_queriers_mut)
100    }
101}