use std::rc::{ Rc, Weak };
use std::cell::{ RefCell, Ref, RefMut };
use std::hash::{ Hash, Hasher };
use std::fmt::{ self, Display, Formatter };
use error::{ Error, Result };
use unicode_segmentation::UnicodeSegmentation;
macro_rules! assoc_map {
($ty: ident, $($key: expr => $val: expr),*) => ({
let mut _tmp = ::std::collections::$ty::new();
$(
_tmp.insert($key.into(), $val.into());
)*
_tmp
})
}
macro_rules! btree_map {
($($key: expr => $val: expr),*) => {
assoc_map!(BTreeMap, $($key => $val),*)
};
($($key: expr => $val: expr),+,) => { btree_map!($($key => $val),+) };
}
#[derive(Debug, Clone, Copy)]
pub struct PackageInfo {
pub name: &'static str,
pub version: &'static str,
pub authors: &'static str,
pub description: &'static str,
pub home_page: &'static str,
}
pub static PACKAGE_INFO: PackageInfo = PackageInfo {
name: env!["CARGO_PKG_NAME"],
version: env!["CARGO_PKG_VERSION"],
authors: env!["CARGO_PKG_AUTHORS"],
description: env!["CARGO_PKG_DESCRIPTION"],
home_page: env!["CARGO_PKG_HOMEPAGE"],
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum DiagnosticKind {
Default,
Info,
Highlight,
Success,
Error,
}
impl Default for DiagnosticKind {
fn default() -> Self {
DiagnosticKind::Default
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Diagnostic<T> {
value: T,
kind: DiagnosticKind,
}
impl<T> Diagnostic<T> {
pub fn new(value: T, kind: DiagnosticKind) -> Self {
Diagnostic { value, kind }
}
pub fn into_inner(self) -> T {
self.value
}
pub fn kind(&self) -> DiagnosticKind {
self.kind
}
}
impl<T> AsRef<T> for Diagnostic<T> {
fn as_ref(&self) -> &T {
&self.value
}
}
impl<T> AsMut<T> for Diagnostic<T> {
fn as_mut(&mut self) -> &mut T {
&mut self.value
}
}
impl<T> From<T> for Diagnostic<T> {
fn from(value: T) -> Self {
Self::new(value, DiagnosticKind::Default)
}
}
impl<T> Display for Diagnostic<T> where T: Display {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let reset = "\x1b[0m";
let color = match self.kind {
DiagnosticKind::Default => "",
DiagnosticKind::Info => "\x1b[1;33m",
DiagnosticKind::Highlight => "\x1b[1;36m",
DiagnosticKind::Success => "\x1b[1;32m",
DiagnosticKind::Error => "\x1b[1;31m",
};
write!(f, "{}{}{}{}", reset, color, self.value, reset)
}
}
pub fn grapheme_count(string: &str) -> usize {
string.graphemes(true).count()
}
pub fn grapheme_count_by<P: Fn(&str) -> bool>(string: &str, pred: P) -> usize {
string.graphemes(true).filter(|&g| pred(g)).count()
}
pub trait SkipN: Iterator {
fn skip_n(&mut self, n: usize) {
for _ in 0..n {
self.next();
}
}
}
impl<T: Iterator> SkipN for T {}
#[derive(Debug, Default)]
pub struct RcCell<T: ?Sized> {
ptr: Rc<RefCell<T>>,
}
impl<T> RcCell<T> {
pub fn new(value: T) -> Self {
RcCell {
ptr: Rc::new(RefCell::new(value))
}
}
pub fn borrow(&self) -> Result<Ref<T>> {
self.ptr.try_borrow().map_err(From::from)
}
pub fn borrow_mut(&self) -> Result<RefMut<T>> {
self.ptr.try_borrow_mut().map_err(From::from)
}
pub fn to_weak(&self) -> WkCell<T> {
WkCell {
ptr: Rc::downgrade(&self.ptr)
}
}
pub fn strong_count(&self) -> usize {
Rc::strong_count(&self.ptr)
}
pub fn weak_count(&self) -> usize {
Rc::weak_count(&self.ptr)
}
}
impl<T> Clone for RcCell<T> {
fn clone(&self) -> Self {
RcCell {
ptr: self.ptr.clone()
}
}
}
impl<T> PartialEq for RcCell<T> {
fn eq(&self, other: &Self) -> bool {
Rc::ptr_eq(&self.ptr, &other.ptr)
}
}
impl<T> Eq for RcCell<T> {}
impl<T> Hash for RcCell<T> {
fn hash<H: Hasher>(&self, hasher: &mut H) {
self.ptr.as_ptr().hash(hasher)
}
}
impl<T> Display for RcCell<T> where T: Display {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self.borrow() {
Ok(ptr) => ptr.fmt(f),
Err(_) => f.write_str("<cannot borrow RcCell>"),
}
}
}
impl<T> From<T> for RcCell<T> {
fn from(value: T) -> Self {
RcCell::new(value)
}
}
#[derive(Debug)]
pub struct WkCell<T: ?Sized> {
ptr: Weak<RefCell<T>>,
}
impl<T> WkCell<T> {
pub fn new() -> Self {
WkCell {
ptr: Weak::new()
}
}
pub fn to_rc(&self) -> Result<RcCell<T>> {
self.ptr.upgrade().map(|rc| RcCell { ptr: rc }).ok_or(Error::Strongify)
}
}
impl<T> Clone for WkCell<T> {
fn clone(&self) -> Self {
WkCell {
ptr: self.ptr.clone()
}
}
}
impl<T> Default for WkCell<T> {
fn default() -> Self {
WkCell::new()
}
}
impl<T> Display for WkCell<T> where RcCell<T>: Display {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self.to_rc() {
Ok(rc) => rc.fmt(f),
Err(_) => f.write_str("<cannot strongify WkCell>"),
}
}
}