xref: /aosp_15_r20/external/cronet/third_party/rust/chromium_crates_io/vendor/fend-core-1.4.6/src/scope.rs (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 use crate::ident::Ident;
2 use crate::result::FResult;
3 use crate::serialize::{Deserialize, Serialize};
4 use crate::value::Value;
5 use crate::Attrs;
6 use crate::{ast::Expr, error::Interrupt};
7 use std::io;
8 use std::sync::Arc;
9 
10 #[derive(Debug, Clone)]
11 enum ScopeValue {
12 	LazyVariable(Expr, Option<Arc<Scope>>),
13 }
14 
15 impl ScopeValue {
compare<I: Interrupt>(&self, other: &Self, int: &I) -> FResult<bool>16 	pub(crate) fn compare<I: Interrupt>(&self, other: &Self, int: &I) -> FResult<bool> {
17 		let Self::LazyVariable(a1, a2) = self;
18 		let Self::LazyVariable(b1, b2) = other;
19 		Ok(a1.compare(b1, int)? && compare_option_arc_scope(a2, b2, int)?)
20 	}
21 
eval<I: Interrupt>( &self, attrs: Attrs, context: &mut crate::Context, int: &I, ) -> FResult<Value>22 	fn eval<I: Interrupt>(
23 		&self,
24 		attrs: Attrs,
25 		context: &mut crate::Context,
26 		int: &I,
27 	) -> FResult<Value> {
28 		match self {
29 			Self::LazyVariable(expr, scope) => {
30 				let value = crate::ast::evaluate(expr.clone(), scope.clone(), attrs, context, int)?;
31 				Ok(value)
32 			}
33 		}
34 	}
35 
serialize(&self, write: &mut impl io::Write) -> FResult<()>36 	pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FResult<()> {
37 		match self {
38 			Self::LazyVariable(e, s) => {
39 				e.serialize(write)?;
40 				match s {
41 					None => false.serialize(write)?,
42 					Some(s) => {
43 						true.serialize(write)?;
44 						s.serialize(write)?;
45 					}
46 				}
47 			}
48 		}
49 		Ok(())
50 	}
51 
deserialize(read: &mut impl io::Read) -> FResult<Self>52 	pub(crate) fn deserialize(read: &mut impl io::Read) -> FResult<Self> {
53 		Ok(Self::LazyVariable(Expr::deserialize(read)?, {
54 			if bool::deserialize(read)? {
55 				None
56 			} else {
57 				Some(Arc::new(Scope::deserialize(read)?))
58 			}
59 		}))
60 	}
61 }
62 
63 #[derive(Debug, Clone)]
64 pub(crate) struct Scope {
65 	ident: Ident,
66 	value: ScopeValue,
67 	inner: Option<Arc<Scope>>,
68 }
69 
compare_option_arc_scope<I: Interrupt>( a: &Option<Arc<Scope>>, b: &Option<Arc<Scope>>, int: &I, ) -> FResult<bool>70 pub(crate) fn compare_option_arc_scope<I: Interrupt>(
71 	a: &Option<Arc<Scope>>,
72 	b: &Option<Arc<Scope>>,
73 	int: &I,
74 ) -> FResult<bool> {
75 	Ok(match (a, b) {
76 		(None, None) => true,
77 		(Some(a), Some(b)) => a.compare(b, int)?,
78 		_ => false,
79 	})
80 }
81 
82 impl Scope {
compare<I: Interrupt>(&self, other: &Self, int: &I) -> FResult<bool>83 	pub(crate) fn compare<I: Interrupt>(&self, other: &Self, int: &I) -> FResult<bool> {
84 		Ok(self.ident == other.ident
85 			&& self.value.compare(&other.value, int)?
86 			&& compare_option_arc_scope(&self.inner, &other.inner, int)?)
87 	}
88 
serialize(&self, write: &mut impl io::Write) -> FResult<()>89 	pub(crate) fn serialize(&self, write: &mut impl io::Write) -> FResult<()> {
90 		self.ident.serialize(write)?;
91 		self.value.serialize(write)?;
92 		match &self.inner {
93 			None => false.serialize(write)?,
94 			Some(s) => {
95 				true.serialize(write)?;
96 				s.serialize(write)?;
97 			}
98 		}
99 		Ok(())
100 	}
101 
deserialize(read: &mut impl io::Read) -> FResult<Self>102 	pub(crate) fn deserialize(read: &mut impl io::Read) -> FResult<Self> {
103 		Ok(Self {
104 			ident: Ident::deserialize(read)?,
105 			value: ScopeValue::deserialize(read)?,
106 			inner: {
107 				if bool::deserialize(read)? {
108 					None
109 				} else {
110 					Some(Arc::new(Self::deserialize(read)?))
111 				}
112 			},
113 		})
114 	}
115 
with_scope_value(ident: Ident, value: ScopeValue, inner: Option<Arc<Self>>) -> Self116 	const fn with_scope_value(ident: Ident, value: ScopeValue, inner: Option<Arc<Self>>) -> Self {
117 		Self {
118 			ident,
119 			value,
120 			inner,
121 		}
122 	}
123 
with_variable( name: Ident, expr: Expr, scope: Option<Arc<Self>>, inner: Option<Arc<Self>>, ) -> Self124 	pub(crate) fn with_variable(
125 		name: Ident,
126 		expr: Expr,
127 		scope: Option<Arc<Self>>,
128 		inner: Option<Arc<Self>>,
129 	) -> Self {
130 		Self::with_scope_value(name, ScopeValue::LazyVariable(expr, scope), inner)
131 	}
132 
get<I: Interrupt>( &self, ident: &Ident, attrs: Attrs, context: &mut crate::Context, int: &I, ) -> FResult<Option<Value>>133 	pub(crate) fn get<I: Interrupt>(
134 		&self,
135 		ident: &Ident,
136 		attrs: Attrs,
137 		context: &mut crate::Context,
138 		int: &I,
139 	) -> FResult<Option<Value>> {
140 		if self.ident.as_str() == ident.as_str() {
141 			let value = self.value.eval(attrs, context, int)?;
142 			Ok(Some(value))
143 		} else {
144 			self.inner
145 				.as_ref()
146 				.map_or_else(|| Ok(None), |inner| inner.get(ident, attrs, context, int))
147 		}
148 	}
149 }
150