scratch_test_model/scopes/
project_doc.rs1use crate::{
2 Id,
3 attrs::RefBlock,
4 blocks::BlockKindUnit,
5 error::BlockReferenceInvalid,
6 scopes::{block_wrapper::BlockWrapper, target_blocks::WrappableKind},
7};
8
9use super::target::Target;
10use itertools::Itertools;
11use svalue::ARc;
12
13#[derive(Debug, derive_getters::Getters, Clone, PartialEq)]
19pub struct ProjectDoc {
20 pub(crate) targets: ARc<[Target]>,
22 pub(crate) semver: Option<ARc<str>>,
27}
28
29#[derive(Debug, thiserror::Error, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
31#[error("The requested block id isn't associated with a valid block")]
32pub struct NoValidBlockForId(());
33
34impl ProjectDoc {
35 pub fn ids_with_opcodes(&self) -> impl Iterator<Item = (&Id, BlockKindUnit)> {
36 self.targets()
37 .iter()
38 .flat_map(|t| t.blocks().ids_with_opcodes())
39 }
40
41 pub fn su_ids_with_blocks(&self) -> impl Iterator<Item = (&Id, BlockKindUnit)> {
42 self.ids_with_opcodes().sorted().unique()
43 }
44 pub fn get_block<'a>(
52 &'a self,
53 id: &crate::Id,
54 ) -> Result<&'a ARc<BlockWrapper>, NoValidBlockForId> {
55 self.targets()
56 .iter()
57 .flat_map(|trgt| trgt.blocks().iter_blocks())
58 .find(|blk| blk.id() == id)
59 .ok_or(NoValidBlockForId(()))
60 }
61
62 pub fn get_specific_kind<T: WrappableKind + PartialEq>(
63 &self,
64 reference: &RefBlock<T>,
65 ) -> Result<&T, BlockReferenceInvalid> {
66 self.targets()
67 .iter()
68 .map(|trgt| trgt.blocks().get_specific_kind(reference))
69 .find(|blk| !matches!(blk, Err(BlockReferenceInvalid::IdNotFound)))
70 .ok_or(BlockReferenceInvalid::IdNotFound)?
71 }
72 pub fn get_specific_with_wrapper<T: WrappableKind>(
73 &self,
74 reference: &RefBlock<T>,
75 ) -> Result<(&T, &svalue::ARc<BlockWrapper>), BlockReferenceInvalid> {
76 self.targets()
77 .iter()
78 .map(|trgt| trgt.blocks().get_specific_with_wrapper(reference))
79 .find(|blk| !matches!(blk, Err(BlockReferenceInvalid::IdNotFound)))
80 .ok_or(BlockReferenceInvalid::IdNotFound)?
81 }
82}