use core::errors::Error;
use core::{CoreFlavor, Import, Loc, RpName, RpRequiredPackage, RpVersionedPackage, Span};
use naming::Naming;
use std::collections::HashMap;
use std::rc::Rc;
pub struct Scope<I> {
package: RpVersionedPackage,
keywords: Rc<HashMap<String, String>>,
field_ident_naming: Option<Box<Naming>>,
endpoint_ident_naming: Option<Box<Naming>>,
import: I,
pub endpoint_naming: Option<Box<Naming>>,
pub field_naming: Option<Box<Naming>>,
pub prefixes: HashMap<String, RpVersionedPackage>,
path: Vec<String>,
}
impl<I> Scope<I> {
pub fn new(
package: RpVersionedPackage,
keywords: Rc<HashMap<String, String>>,
field_ident_naming: Option<Box<Naming>>,
endpoint_ident_naming: Option<Box<Naming>>,
import: I,
) -> Scope<I> {
Self {
package,
keywords,
field_ident_naming,
endpoint_ident_naming,
import,
endpoint_naming: None,
field_naming: None,
prefixes: HashMap::new(),
path: vec![],
}
}
pub fn push<S: AsRef<str>>(&mut self, name: S) {
self.path.push(name.as_ref().to_string());
}
pub fn pop(&mut self) {
self.path.pop();
}
pub fn lookup_prefix(&self, prefix: &str) -> Option<RpVersionedPackage> {
self.prefixes.get(prefix).map(Clone::clone)
}
pub fn package(&self) -> RpVersionedPackage {
self.package.clone()
}
pub fn as_name(&self, span: Span) -> Loc<RpName<CoreFlavor>> {
Loc::new(
RpName {
prefix: None,
package: self.package(),
parts: self.path.clone(),
},
span,
)
}
pub fn endpoint_naming(&self) -> Option<&Naming> {
self.endpoint_naming.as_ref().map(AsRef::as_ref)
}
pub fn field_naming(&self) -> Option<&Naming> {
self.field_naming.as_ref().map(AsRef::as_ref)
}
pub fn field_ident_naming(&self) -> Option<&Naming> {
self.field_ident_naming.as_ref().map(AsRef::as_ref)
}
pub fn endpoint_ident_naming(&self) -> Option<&Naming> {
self.endpoint_ident_naming.as_ref().map(AsRef::as_ref)
}
pub fn keyword(&self, identifier: &str) -> Option<&str> {
self.keywords.get(identifier).map(|s| s.as_str())
}
}
impl<I> Scope<I>
where
I: Import,
{
pub fn import(
&mut self,
package: &RpRequiredPackage,
) -> Result<Option<RpVersionedPackage>, Error> {
self.import.import(package)
}
}
#[cfg(test)]
mod tests {
use core::{RpPackage, RpVersionedPackage};
use scope::Scope;
use std::collections::HashMap;
use std::rc::Rc;
#[test]
pub fn test_scope() {
let package = RpVersionedPackage::new(RpPackage::empty(), None);
let keywords = Rc::new(HashMap::new());
let mut s = Scope::new(package, keywords, None, None, ());
s.push("foo");
s.push("bar");
assert_eq!(vec!["foo".to_owned(), "bar".to_owned()], s.path);
}
}