// Copyright 2018 Mozilla // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use // this file except in compliance with the License. You may obtain a copy of the // License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. use ::std::rc::{ Rc, }; use ::std::sync::{ Arc, }; pub trait FromRc { fn from_rc(val: Rc) -> Self; fn from_arc(val: Arc) -> Self; } impl FromRc for Rc where T: Sized + Clone { fn from_rc(val: Rc) -> Self { val.clone() } fn from_arc(val: Arc) -> Self { match ::std::sync::Arc::::try_unwrap(val) { Ok(v) => Self::new(v), Err(r) => Self::new(r.cloned()), } } } impl FromRc for Arc where T: Sized + Clone { fn from_rc(val: Rc) -> Self { match ::std::rc::Rc::::try_unwrap(val) { Ok(v) => Self::new(v), Err(r) => Self::new(r.cloned()), } } fn from_arc(val: Arc) -> Self { val.clone() } } impl FromRc for Box where T: Sized + Clone { fn from_rc(val: Rc) -> Self { match ::std::rc::Rc::::try_unwrap(val) { Ok(v) => Self::new(v), Err(r) => Self::new(r.cloned()), } } fn from_arc(val: Arc) -> Self { match ::std::sync::Arc::::try_unwrap(val) { Ok(v) => Self::new(v), Err(r) => Self::new(r.cloned()), } } } // We do this a lot for errors. pub trait Cloned { fn cloned(&self) -> T; fn to_value_rc(&self) -> ValueRc; } impl Cloned for Rc where T: Sized + Clone { fn cloned(&self) -> T { (*self.as_ref()).clone() } fn to_value_rc(&self) -> ValueRc { ValueRc::from_rc(self.clone()) } } impl Cloned for Arc where T: Sized + Clone { fn cloned(&self) -> T { (*self.as_ref()).clone() } fn to_value_rc(&self) -> ValueRc { ValueRc::from_arc(self.clone()) } } impl Cloned for Box where T: Sized + Clone { fn cloned(&self) -> T { self.as_ref().clone() } fn to_value_rc(&self) -> ValueRc { ValueRc::new(self.cloned()) } } /// /// This type alias exists to allow us to use different boxing mechanisms for values. /// This type must implement `FromRc` and `Cloned`, and a `From` implementation must exist for /// `TypedValue`. /// pub type ValueRc = Arc;