Skip to content

Commit 8f43bfc

Browse files
committed
Rework FunctionDefinitionContext
Its not clear why `Arc` was used internally in the first place when `Box` just works. It thus removes the need to rely on `Arc::get_mut` or `Arc::try_unwrap` which simplifies substantially the implementation.
1 parent fbd5b7e commit 8f43bfc

File tree

1 file changed

+38
-46
lines changed

1 file changed

+38
-46
lines changed

engine/src/functions.rs

Lines changed: 38 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,8 @@ use crate::{
44
};
55
use std::any::Any;
66
use std::convert::TryFrom;
7-
use std::{
8-
fmt::{self, Debug},
9-
iter::once,
10-
sync::Arc,
11-
};
7+
use std::fmt::{self, Debug};
8+
use std::iter::once;
129
use thiserror::Error;
1310

1411
pub(crate) struct ExactSizeChain<A, B>
@@ -274,16 +271,16 @@ impl<'a> FunctionParam<'a> {
274271
/// Context that can be created and used
275272
/// when parsing a function call
276273
pub struct FunctionDefinitionContext {
277-
inner: Arc<dyn Any + Send + Sync>,
278-
clone_cb: fn(&(dyn Any + Send + Sync)) -> Arc<dyn Any + Send + Sync>,
274+
inner: Box<dyn Any + Send + Sync>,
275+
clone_cb: fn(&(dyn Any + Send + Sync)) -> Box<dyn Any + Send + Sync>,
279276
fmt_cb: fn(&(dyn Any + Send + Sync), &mut std::fmt::Formatter<'_>) -> std::fmt::Result,
280277
}
281278

282279
impl FunctionDefinitionContext {
283280
fn clone_any<T: Any + Clone + Send + Sync>(
284281
t: &(dyn Any + Send + Sync),
285-
) -> Arc<dyn Any + Send + Sync> {
286-
Arc::new(t.downcast_ref::<T>().unwrap().clone())
282+
) -> Box<dyn Any + Send + Sync> {
283+
Box::new(t.downcast_ref::<T>().unwrap().clone())
287284
}
288285

289286
fn fmt_any<T: Any + Debug + Send + Sync>(
@@ -297,26 +294,30 @@ impl FunctionDefinitionContext {
297294
/// object of type `T`
298295
pub fn new<T: Any + Clone + Debug + Send + Sync>(t: T) -> Self {
299296
Self {
300-
inner: Arc::new(t),
297+
inner: Box::new(t),
301298
clone_cb: Self::clone_any::<T>,
302299
fmt_cb: Self::fmt_any::<T>,
303300
}
304301
}
302+
305303
/// Returns a reference to the underlying Any object
306304
pub fn as_any_ref(&self) -> &(dyn Any + Send + Sync) {
307305
&*self.inner
308306
}
307+
309308
/// Returns a mutable reference to the underlying Any object
310309
pub fn as_any_mut(&mut self) -> &mut (dyn Any + Send + Sync) {
311-
Arc::get_mut(&mut self.inner).unwrap()
310+
&mut self.inner
312311
}
313-
/// Converts current `FunctionDefinitionContext` to `Box<dyn Dy>`
314-
pub fn into_any(self) -> Arc<dyn Any + Send + Sync> {
312+
313+
/// Converts current `FunctionDefinitionContext` to `Box<dyn Any>`
314+
pub fn into_any(self) -> Box<dyn Any + Send + Sync> {
315315
let Self { inner, .. } = self;
316316
inner
317317
}
318+
318319
/// Attempt to downcast the context to a concrete type.
319-
pub fn downcast<T: Any + Send + Sync>(self) -> Result<Arc<T>, Self> {
320+
pub fn downcast<T: Any + Send + Sync>(self) -> Result<Box<T>, Self> {
320321
let Self {
321322
inner,
322323
clone_cb,
@@ -329,27 +330,14 @@ impl FunctionDefinitionContext {
329330
})
330331
}
331332

332-
/// Attempt to extract the concrete value stored in the context.
333-
pub fn try_unwrap<T: Any + Send + Sync>(self) -> Result<T, Self> {
334-
self.downcast::<T>().map(|val| match Arc::try_unwrap(val) {
335-
Ok(val) => val,
336-
Err(_) => unreachable!(),
337-
})
333+
/// Returns some reference to the inner value if it is of type T, or None if it isn’t.
334+
pub fn downcast_ref<T: Any + Send + Sync>(&self) -> Option<&T> {
335+
self.inner.downcast_ref::<T>()
338336
}
339-
}
340-
341-
impl<T: Any> std::convert::AsRef<T> for FunctionDefinitionContext {
342-
fn as_ref(&self) -> &T {
343-
self.inner.downcast_ref::<T>().unwrap()
344-
}
345-
}
346337

347-
impl<T: Any> std::convert::AsMut<T> for FunctionDefinitionContext {
348-
fn as_mut(&mut self) -> &mut T {
349-
Arc::get_mut(&mut self.inner)
350-
.unwrap()
351-
.downcast_mut::<T>()
352-
.unwrap()
338+
/// Returns some mutable reference to the inner value if it is of type T, or None if it isn’t.
339+
pub fn downcast_mut<T: Any + Send + Sync>(&mut self) -> Option<&mut T> {
340+
self.inner.downcast_mut::<T>()
353341
}
354342
}
355343

@@ -533,29 +521,33 @@ mod tests {
533521

534522
#[test]
535523
fn test_function_definition_context() {
536-
let ctx1 = FunctionDefinitionContext::new(Some(42u8));
524+
let mut ctx1 = FunctionDefinitionContext::new(42u8);
537525

538526
assert_eq!(
539-
"FunctionDefinitionContext(Some(42))".to_owned(),
527+
"FunctionDefinitionContext(42)".to_owned(),
540528
format!("{ctx1:?}")
541529
);
542530

543-
assert_eq!(
544-
ctx1.as_any_ref().downcast_ref::<Option<u8>>().unwrap(),
545-
&Some(42u8)
546-
);
531+
assert_eq!(ctx1.downcast_ref::<u8>(), Some(&42u8));
547532

548533
let ctx2 = ctx1.clone();
549534

550-
let value = ctx1.downcast::<Option<u8>>().unwrap();
535+
assert_eq!(ctx2.downcast_ref::<u8>(), Some(&42u8));
551536

552-
assert_eq!(value, Arc::new(Some(42u8)));
537+
*ctx1.downcast_mut::<u8>().unwrap() = 255u8;
553538

554-
assert_eq!(
555-
ctx2.as_any_ref().downcast_ref::<Option<u8>>().unwrap(),
556-
&*value
557-
);
539+
let value = ctx1.downcast::<u8>().unwrap();
540+
541+
assert_eq!(*value, 255u8);
542+
543+
assert_eq!(*ctx2.downcast::<u8>().unwrap(), 42u8);
544+
545+
fn is_send<T: Send>() {}
546+
547+
is_send::<FunctionDefinitionContext>();
548+
549+
fn is_sync<T: Sync>() {}
558550

559-
assert_eq!(ctx2.try_unwrap::<Option<u8>>().unwrap(), Some(42u8));
551+
is_sync::<FunctionDefinitionContext>();
560552
}
561553
}

0 commit comments

Comments
 (0)