orphanage 0.5.6

Random collection of stuff that is still searching for a home.
Documentation
// Enabling this test casuses the linker to go boom on macOS, due to knus
// generating symbol names that are too long for the linker.  Until a solution
// is found for this, keep this disabled so `cargo test --all-features` will
// pass.
//! ```no_run
//! use orphanage::parsers::ExpandedPath;
//!
//! #[derive(Debug, knus::Decode)]
//! struct Config {
//!   #[knus(child, unwrap(argument))]
//!   dbpath: ExpandedPath
//! }
//!
//! let cfg = knus::parse::<Config>(
//!   "test.kdl",
//!   r#"
//! dbpath "~/tmp/hello"
//! "#
//! ).unwrap();
//! ```

use std::path::PathBuf;

use knus::{
  DecodeScalar,
  ast::{Literal, TypeName},
  decode::{Context, Kind},
  errors::{DecodeError, ExpectedType},
  span::Spanned,
  traits::ErrorSpan
};

use super::ExpandedPath;

impl<S: ErrorSpan> DecodeScalar<S> for ExpandedPath {
  fn raw_decode(
    val: &Spanned<Literal, S>,
    ctx: &mut Context<S>
  ) -> Result<Self, DecodeError<S>> {
    if let Literal::String(s) = &**val {
      match shellexpand::full(s) {
        Ok(pth) => {
          let pth = pth.into_owned();
          Ok(Self(PathBuf::from(pth)))
        }
        Err(e) => {
          ctx.emit_error(DecodeError::conversion(val, e));
          Ok(Self::default())
        }
      }
    } else {
      ctx.emit_error(DecodeError::scalar_kind(Kind::String, val));
      Ok(Self::default())
    }
  }

  fn type_check(
    type_name: &Option<Spanned<TypeName, S>>,
    ctx: &mut Context<S>
  ) {
    if let Some(typ) = type_name {
      ctx.emit_error(DecodeError::TypeName {
        span: typ.span().clone(),
        found: Some((**typ).clone()),
        expected: ExpectedType::no_type(),
        rust_type: "ExpandedPath"
      });
    }
  }
}

// vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 :