use std::{cell::RefCell, rc::Rc}; use napi::bindgen_prelude::*; pub struct Repository { dir: String, } impl Repository { fn remote(&self) -> Remote { Remote { inner: self } } } pub struct Remote<'repo> { inner: &'repo Repository, } impl<'repo> Remote<'repo> { fn name(&self) -> String { "origin".to_owned() } } #[napi] pub struct JsRepo { inner: Repository, } #[napi] impl JsRepo { #[napi(constructor)] pub fn new(dir: String) -> Self { JsRepo { inner: Repository { dir }, } } #[napi] pub fn remote(&self, reference: Reference, env: Env) -> Result { Ok(JsRemote { inner: reference.share_with(env, |repo| Ok(repo.inner.remote()))?, }) } } #[napi] pub struct JsRemote { inner: SharedReference>, } #[napi] impl JsRemote { #[napi] pub fn name(&self) -> String { self.inner.name() } } struct OwnedStyleSheet { rules: Vec, } #[napi] pub struct CSSRuleList { owned: Rc>, } #[napi] impl CSSRuleList { #[napi] pub fn get_rules(&self) -> Vec { self.owned.borrow().rules.to_vec() } } #[napi] pub struct CSSStyleSheet { inner: Rc>, rules: Reference, } #[napi] impl CSSStyleSheet { #[napi(constructor)] pub fn new(env: Env, rules: Vec) -> Result { let inner = Rc::new(RefCell::new(OwnedStyleSheet { rules })); let rules = CSSRuleList::into_reference( CSSRuleList { owned: inner.clone(), }, env, )?; Ok(CSSStyleSheet { inner, rules }) } #[napi(getter)] pub fn rules(&self, env: Env) -> Result> { self.rules.clone(env) } }