1use crate::prelude::TractResult;
2use std::borrow::Cow;
3
4pub trait ResolveTo<Concrete> {
5 type Param: ?Sized;
6 fn resolve(&self, param: &Self::Param) -> TractResult<Concrete>;
7}
8
9#[derive(Debug, Clone, Hash, PartialEq, Eq)]
10pub enum GeometryBound<Symbolic, Concrete> {
11 Symbolic(Symbolic),
12 Concrete(Concrete),
13}
14
15impl<S: ResolveTo<C>, C: Clone> GeometryBound<S, C> {
16 pub fn is_concrete(&self) -> bool {
17 match self {
18 GeometryBound::Concrete { .. } => true,
19 GeometryBound::Symbolic { .. } => false,
20 }
21 }
22
23 pub fn into_concrete(self, param: &S::Param) -> TractResult<Self> {
24 match self {
25 Self::Symbolic(sym) => Ok(Self::Concrete(sym.resolve(param)?)),
26 Self::Concrete(conc) => Ok(Self::Concrete(conc)),
27 }
28 }
29
30 pub fn to_concrete(&self, param: &S::Param) -> TractResult<Cow<C>> {
31 match self {
32 Self::Symbolic(sym) => Ok(Cow::Owned(sym.resolve(param)?)),
33 Self::Concrete(conc) => Ok(Cow::Borrowed(conc)),
34 }
35 }
36
37 pub fn as_concrete(&self) -> Option<&C> {
38 if let Self::Concrete(conc) = self {
39 Some(conc)
40 } else {
41 None
42 }
43 }
44
45 pub fn optimize_if(self, param: Option<&S::Param>) -> TractResult<Self> {
46 if let Some(param) = param {
47 self.into_concrete(param)
48 } else {
49 Ok(self)
50 }
51 }
52}
53
54impl<S, C> From<S> for GeometryBound<S, C> {
55 fn from(s: S) -> Self {
56 GeometryBound::Symbolic(s)
57 }
58}