<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use hoedown::{Markdown, Html as MdHtml};
use hoedown::renderer::html::Flags as HtmlFlags;
use hoedown::renderer::Render;

use result::Result;
use error::MarkdownErrorKind;
use libimagerror::into::IntoError;

pub type HTML = String;

pub fn to_html(buffer: &str) -> Result<HTML> {
    let md = Markdown::new(buffer);
    let mut html = MdHtml::new(HtmlFlags::empty(), 0);
    html.render(&md)
        .to_str()
        .map(String::from)
        .map_err(Box::new)
        .map_err(|e| MarkdownErrorKind::MarkdownRenderError.into_error_with_cause(e))
}

pub mod iter {
    use result::Result;
    use libimagstore::store::Entry;
    use super::HTML;
    use super::to_html;

    pub struct ToHtmlIterator<I: Iterator<Item = Entry>> {
        i: I
    }

    impl<I: Iterator<Item = Entry>> ToHtmlIterator<I> {

        pub fn new(i: I) -> ToHtmlIterator<I> {
            ToHtmlIterator { i: i }
        }

    }

    impl<I: Iterator<Item = Entry>> Iterator for ToHtmlIterator<I> {
        type Item = Result<HTML>;

        fn next(&mut self) -> Option<Self::Item> {
            self.i.next().map(|entry| to_html(&entry.get_content()[..]))
        }

    }

    impl<I: Iterator<Item = Entry>> From<I> for ToHtmlIterator<I> {

        fn from(obj: I) -> ToHtmlIterator<I> {
            ToHtmlIterator::new(obj)
        }

    }

    /// Iterate over `(Entry, Result<HTML>)` tuples
    pub struct WithHtmlIterator<I: Iterator<Item = Entry>> {
        i: I
    }

    impl<I: Iterator<Item = Entry>> WithHtmlIterator<I> {

        fn new(i: I) -> WithHtmlIterator<I> {
            WithHtmlIterator { i: i }
        }

    }

    impl<I: Iterator<Item = Entry>> Iterator for WithHtmlIterator<I> {
        type Item = (Entry, Result<HTML>);

        fn next(&mut self) -> Option<Self::Item> {
            self.i.next().map(|entry| {
                let html = to_html(&entry.get_content()[..]);
                (entry, html)
            })
        }

    }

}
<commit_msg>Add "pub" to constructor fn<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use hoedown::{Markdown, Html as MdHtml};
use hoedown::renderer::html::Flags as HtmlFlags;
use hoedown::renderer::Render;

use result::Result;
use error::MarkdownErrorKind;
use libimagerror::into::IntoError;

pub type HTML = String;

pub fn to_html(buffer: &str) -> Result<HTML> {
    let md = Markdown::new(buffer);
    let mut html = MdHtml::new(HtmlFlags::empty(), 0);
    html.render(&md)
        .to_str()
        .map(String::from)
        .map_err(Box::new)
        .map_err(|e| MarkdownErrorKind::MarkdownRenderError.into_error_with_cause(e))
}

pub mod iter {
    use result::Result;
    use libimagstore::store::Entry;
    use super::HTML;
    use super::to_html;

    pub struct ToHtmlIterator<I: Iterator<Item = Entry>> {
        i: I
    }

    impl<I: Iterator<Item = Entry>> ToHtmlIterator<I> {

        pub fn new(i: I) -> ToHtmlIterator<I> {
            ToHtmlIterator { i: i }
        }

    }

    impl<I: Iterator<Item = Entry>> Iterator for ToHtmlIterator<I> {
        type Item = Result<HTML>;

        fn next(&mut self) -> Option<Self::Item> {
            self.i.next().map(|entry| to_html(&entry.get_content()[..]))
        }

    }

    impl<I: Iterator<Item = Entry>> From<I> for ToHtmlIterator<I> {

        fn from(obj: I) -> ToHtmlIterator<I> {
            ToHtmlIterator::new(obj)
        }

    }

    /// Iterate over `(Entry, Result<HTML>)` tuples
    pub struct WithHtmlIterator<I: Iterator<Item = Entry>> {
        i: I
    }

    impl<I: Iterator<Item = Entry>> WithHtmlIterator<I> {

        pub fn new(i: I) -> WithHtmlIterator<I> {
            WithHtmlIterator { i: i }
        }

    }

    impl<I: Iterator<Item = Entry>> Iterator for WithHtmlIterator<I> {
        type Item = (Entry, Result<HTML>);

        fn next(&mut self) -> Option<Self::Item> {
            self.i.next().map(|entry| {
                let html = to_html(&entry.get_content()[..]);
                (entry, html)
            })
        }

    }

}
<|endoftext|>


<commit_before>use std::sync::{Arc,Mutex};
use std::collections::HashMap;
use std::io::BufReader;
use webpki;
use rustls::{ResolvesServerCert, SignatureScheme, PrivateKey};
use rustls::sign::{CertifiedKey, RSASigningKey};
use rustls::internal::pemfile;

use sozu_command::messages::{CertificateAndKey, CertFingerprint, AddCertificate, RemoveCertificate};
use sozu_command::certificate::calculate_fingerprint_from_der;

use network::trie::TrieNode;

struct TlsData {
  pub cert:     CertifiedKey,
  pub refcount: usize,
}

pub struct CertificateResolver {
  domains:      TrieNode<CertFingerprint>,
  certificates: HashMap<CertFingerprint, TlsData>,
}

impl CertificateResolver {
  pub fn new() -> CertificateResolver {
    CertificateResolver {
      domains:      TrieNode::root(),
      certificates: HashMap::new(),
    }
  }

  pub fn add_certificate(&mut self, add_certificate: AddCertificate) -> Option<CertFingerprint> {
    if let Some(certified_key) = generate_certified_key(add_certificate.certificate) {
      if add_certificate.names.is_empty() {
        //FIXME: waiting for https://github.com/briansmith/webpki/pull/65 to merge to get the DNS names
        // create a untrusted::Input
        // let input = untrusted::Input::from(&certs[0].0);
        // create an EndEntityCert
        // let ee = webpki::EndEntityCert::from(input).unwrap()
        // get names
        // let dns_names = ee.list_dns_names()
        // names.extend(dns_names.drain(..).map(|name| name.to_String()));
        unimplemented!("the rustls proxy cannot extract the names from the certificate");
      }

      let mut names = add_certificate.names;
      let fingerprint = calculate_fingerprint_from_der(&certified_key.cert[0].0);
      //info!("cert fingerprint: {:?}", fingerprint);

      let data = TlsData {
        cert:     certified_key,
        refcount: 0,
      };

      let fingerprint = CertFingerprint(fingerprint);
      self.certificates.insert(fingerprint.clone(), data);
      for name in names.drain(..) {
        self.domains.domain_insert(name.into_bytes(), fingerprint.clone());
      }

      Some(fingerprint)
    } else {
      None
    }
  }

  pub fn remove_certificate(&mut self, remove_certificate: RemoveCertificate) {
    let must_delete = self.certificates.get(&remove_certificate.fingerprint).map(|data| data.refcount == 0).unwrap_or(false);

    if let Some(data) = self.certificates.get(&remove_certificate.fingerprint) {
      let cert = &data.cert.cert[0];
      if remove_certificate.names.is_empty() {
        //FIXME: waiting for https://github.com/briansmith/webpki/pull/65 to merge to get the DNS names
        // create a untrusted::Input
        // let input = untrusted::Input::from(&certs[0].0);
        // create an EndEntityCert
        // let ee = webpki::EndEntityCert::from(input).unwrap()
        // get names
        // let dns_names = ee.list_dns_names()
        // names.extend(dns_names.drain(..).map(|name| name.to_String()));
        unimplemented!("the rustls proxy cannot extract the names from the certificate");
      }

      let mut names = remove_certificate.names;

      for name in names {
        self.domains.domain_remove(&name.into_bytes());
      }
    }

    if must_delete {
      self.certificates.remove(&remove_certificate.fingerprint);
    }
  }

  pub fn add_front(&mut self, fingerprint: &CertFingerprint) -> bool {
    if self.certificates.contains_key(fingerprint) {
      self.certificates.get_mut(fingerprint).map(|data| data.refcount += 1);
      true
    } else {
      false
    }
  }

  pub fn remove_front(&mut self, fingerprint: &CertFingerprint) {
    self.certificates.get_mut(fingerprint).map(|data| data.refcount -= 1);

    let must_delete = self.certificates.get(fingerprint).map(|data| data.refcount == 0).unwrap_or(false);
    if must_delete {
      self.certificates.remove(fingerprint);
    }
  }
}

pub struct CertificateResolverWrapper(Mutex<CertificateResolver>);

impl CertificateResolverWrapper {
  pub fn new() -> CertificateResolverWrapper {
    CertificateResolverWrapper(Mutex::new(CertificateResolver::new()))
  }

  pub fn add_certificate(&self, add_certificate: AddCertificate) -> Option<CertFingerprint> {
    if let Ok(ref mut resolver) = self.0.try_lock() {
      resolver.add_certificate(add_certificate)
    } else {
      None
    }
  }

  pub fn remove_certificate(&self, remove_certificate: RemoveCertificate) {
    if let Ok(ref mut resolver) = self.0.try_lock() {
      resolver.remove_certificate(remove_certificate)
    }

  }

  pub fn add_front(&self, fingerprint: &CertFingerprint) -> bool {
    if let Ok(ref mut resolver) = self.0.try_lock() {
      resolver.add_front(fingerprint)
    } else {
      false
    }
  }

  pub fn remove_front(&self, fingerprint: &CertFingerprint) {
    if let Ok(ref mut resolver) = self.0.try_lock() {
      resolver.remove_front(fingerprint)
    }
  }
}

impl ResolvesServerCert for CertificateResolverWrapper {
  fn resolve(
        &self,
        server_name: Option<webpki::DNSNameRef>,
        sigschemes: &[SignatureScheme]
    ) -> Option<CertifiedKey> {

    info!("trying to resolve name: {:?} for signature scheme: {:?}", server_name, sigschemes);
    if let Ok(ref mut resolver) = self.0.try_lock() {
      info!("got the resolver");
      if let Some(name) = server_name {
        resolver.domains.print();
        let s: &str = name.into();
        if let Some(kv) = resolver.domains.domain_lookup(s.as_bytes()) {
           info!("looking for certificate for {:?} with fingerprint {:?}", s, kv.1);
           return resolver.certificates.get(&kv.1).as_ref().map(|data| data.cert.clone());
        }
      }
    }

    None
  }
}

pub fn generate_certified_key(certificate_and_key: CertificateAndKey) -> Option<CertifiedKey> {
  let mut chain = Vec::new();

  let mut cert_reader = BufReader::new(certificate_and_key.certificate.as_bytes());
  let parsed_certs = pemfile::certs(&mut cert_reader);

  let fingerprint:Vec<u8> = Vec::new();
  if let Ok(certs) = parsed_certs {
    for cert in certs {
      chain.push(cert);
    }
  } else {
    return None;
  }

  for ref cert in certificate_and_key.certificate_chain.iter() {
    let mut chain_cert_reader = BufReader::new(cert.as_bytes());
    if let Ok(parsed_chain_certs) = pemfile::certs(&mut chain_cert_reader) {
      for cert in parsed_chain_certs {
        chain.push(cert);
      }
    }
  }

  let mut key_reader = BufReader::new(certificate_and_key.key.as_bytes());
  let parsed_key = pemfile::rsa_private_keys(&mut key_reader);

  if let Ok(keys) = parsed_key {
    if !keys.is_empty() {
      if let Ok(signing_key) = RSASigningKey::new(&keys[0]) {
        let certified = CertifiedKey::new(chain, Arc::new(Box::new(signing_key)));
        return Some(certified);
      }
    } else {
      let mut key_reader = BufReader::new(certificate_and_key.key.as_bytes());
      let parsed_key = pemfile::pkcs8_private_keys(&mut key_reader);
      if let Ok(keys) = parsed_key {
        if !keys.is_empty() {
          if let Ok(signing_key) = RSASigningKey::new(&keys[0]) {
            let certified = CertifiedKey::new(chain, Arc::new(Box::new(signing_key)));
            return Some(certified);
          }
        }
      }
    }
  } else {
    error!("could not parse private key: {:?}", parsed_key);
  }

  None
}
<commit_msg>less verbose logs during the rustls handshake<commit_after>use std::sync::{Arc,Mutex};
use std::collections::HashMap;
use std::io::BufReader;
use webpki;
use rustls::{ResolvesServerCert, SignatureScheme, PrivateKey};
use rustls::sign::{CertifiedKey, RSASigningKey};
use rustls::internal::pemfile;

use sozu_command::messages::{CertificateAndKey, CertFingerprint, AddCertificate, RemoveCertificate};
use sozu_command::certificate::calculate_fingerprint_from_der;

use network::trie::TrieNode;

struct TlsData {
  pub cert:     CertifiedKey,
  pub refcount: usize,
}

pub struct CertificateResolver {
  domains:      TrieNode<CertFingerprint>,
  certificates: HashMap<CertFingerprint, TlsData>,
}

impl CertificateResolver {
  pub fn new() -> CertificateResolver {
    CertificateResolver {
      domains:      TrieNode::root(),
      certificates: HashMap::new(),
    }
  }

  pub fn add_certificate(&mut self, add_certificate: AddCertificate) -> Option<CertFingerprint> {
    if let Some(certified_key) = generate_certified_key(add_certificate.certificate) {
      if add_certificate.names.is_empty() {
        //FIXME: waiting for https://github.com/briansmith/webpki/pull/65 to merge to get the DNS names
        // create a untrusted::Input
        // let input = untrusted::Input::from(&certs[0].0);
        // create an EndEntityCert
        // let ee = webpki::EndEntityCert::from(input).unwrap()
        // get names
        // let dns_names = ee.list_dns_names()
        // names.extend(dns_names.drain(..).map(|name| name.to_String()));
        unimplemented!("the rustls proxy cannot extract the names from the certificate");
      }

      let mut names = add_certificate.names;
      let fingerprint = calculate_fingerprint_from_der(&certified_key.cert[0].0);
      //info!("cert fingerprint: {:?}", fingerprint);

      let data = TlsData {
        cert:     certified_key,
        refcount: 0,
      };

      let fingerprint = CertFingerprint(fingerprint);
      self.certificates.insert(fingerprint.clone(), data);
      for name in names.drain(..) {
        self.domains.domain_insert(name.into_bytes(), fingerprint.clone());
      }

      Some(fingerprint)
    } else {
      None
    }
  }

  pub fn remove_certificate(&mut self, remove_certificate: RemoveCertificate) {
    let must_delete = self.certificates.get(&remove_certificate.fingerprint).map(|data| data.refcount == 0).unwrap_or(false);

    if let Some(data) = self.certificates.get(&remove_certificate.fingerprint) {
      let cert = &data.cert.cert[0];
      if remove_certificate.names.is_empty() {
        //FIXME: waiting for https://github.com/briansmith/webpki/pull/65 to merge to get the DNS names
        // create a untrusted::Input
        // let input = untrusted::Input::from(&certs[0].0);
        // create an EndEntityCert
        // let ee = webpki::EndEntityCert::from(input).unwrap()
        // get names
        // let dns_names = ee.list_dns_names()
        // names.extend(dns_names.drain(..).map(|name| name.to_String()));
        unimplemented!("the rustls proxy cannot extract the names from the certificate");
      }

      let mut names = remove_certificate.names;

      for name in names {
        self.domains.domain_remove(&name.into_bytes());
      }
    }

    if must_delete {
      self.certificates.remove(&remove_certificate.fingerprint);
    }
  }

  pub fn add_front(&mut self, fingerprint: &CertFingerprint) -> bool {
    if self.certificates.contains_key(fingerprint) {
      self.certificates.get_mut(fingerprint).map(|data| data.refcount += 1);
      true
    } else {
      false
    }
  }

  pub fn remove_front(&mut self, fingerprint: &CertFingerprint) {
    self.certificates.get_mut(fingerprint).map(|data| data.refcount -= 1);

    let must_delete = self.certificates.get(fingerprint).map(|data| data.refcount == 0).unwrap_or(false);
    if must_delete {
      self.certificates.remove(fingerprint);
    }
  }
}

pub struct CertificateResolverWrapper(Mutex<CertificateResolver>);

impl CertificateResolverWrapper {
  pub fn new() -> CertificateResolverWrapper {
    CertificateResolverWrapper(Mutex::new(CertificateResolver::new()))
  }

  pub fn add_certificate(&self, add_certificate: AddCertificate) -> Option<CertFingerprint> {
    if let Ok(ref mut resolver) = self.0.try_lock() {
      resolver.add_certificate(add_certificate)
    } else {
      None
    }
  }

  pub fn remove_certificate(&self, remove_certificate: RemoveCertificate) {
    if let Ok(ref mut resolver) = self.0.try_lock() {
      resolver.remove_certificate(remove_certificate)
    }

  }

  pub fn add_front(&self, fingerprint: &CertFingerprint) -> bool {
    if let Ok(ref mut resolver) = self.0.try_lock() {
      resolver.add_front(fingerprint)
    } else {
      false
    }
  }

  pub fn remove_front(&self, fingerprint: &CertFingerprint) {
    if let Ok(ref mut resolver) = self.0.try_lock() {
      resolver.remove_front(fingerprint)
    }
  }
}

impl ResolvesServerCert for CertificateResolverWrapper {
  fn resolve(
        &self,
        server_name: Option<webpki::DNSNameRef>,
        sigschemes: &[SignatureScheme]
    ) -> Option<CertifiedKey> {

    trace!("trying to resolve name: {:?} for signature scheme: {:?}", server_name, sigschemes);
    if let Ok(ref mut resolver) = self.0.try_lock() {
      if let Some(name) = server_name {
        //resolver.domains.print();
        let s: &str = name.into();
        if let Some(kv) = resolver.domains.domain_lookup(s.as_bytes()) {
           trace!("looking for certificate for {:?} with fingerprint {:?}", s, kv.1);
           return resolver.certificates.get(&kv.1).as_ref().map(|data| data.cert.clone());
        }
      }
    }

    None
  }
}

pub fn generate_certified_key(certificate_and_key: CertificateAndKey) -> Option<CertifiedKey> {
  let mut chain = Vec::new();

  let mut cert_reader = BufReader::new(certificate_and_key.certificate.as_bytes());
  let parsed_certs = pemfile::certs(&mut cert_reader);

  let fingerprint:Vec<u8> = Vec::new();
  if let Ok(certs) = parsed_certs {
    for cert in certs {
      chain.push(cert);
    }
  } else {
    return None;
  }

  for ref cert in certificate_and_key.certificate_chain.iter() {
    let mut chain_cert_reader = BufReader::new(cert.as_bytes());
    if let Ok(parsed_chain_certs) = pemfile::certs(&mut chain_cert_reader) {
      for cert in parsed_chain_certs {
        chain.push(cert);
      }
    }
  }

  let mut key_reader = BufReader::new(certificate_and_key.key.as_bytes());
  let parsed_key = pemfile::rsa_private_keys(&mut key_reader);

  if let Ok(keys) = parsed_key {
    if !keys.is_empty() {
      if let Ok(signing_key) = RSASigningKey::new(&keys[0]) {
        let certified = CertifiedKey::new(chain, Arc::new(Box::new(signing_key)));
        return Some(certified);
      }
    } else {
      let mut key_reader = BufReader::new(certificate_and_key.key.as_bytes());
      let parsed_key = pemfile::pkcs8_private_keys(&mut key_reader);
      if let Ok(keys) = parsed_key {
        if !keys.is_empty() {
          if let Ok(signing_key) = RSASigningKey::new(&keys[0]) {
            let certified = CertifiedKey::new(chain, Arc::new(Box::new(signing_key)));
            return Some(certified);
          }
        }
      }
    }
  } else {
    error!("could not parse private key: {:?}", parsed_key);
  }

  None
}
<|endoftext|>


<commit_before>use git2::Error as Git2Error;

use libimagstore::hook::error::HookError as HE;
use libimagstore::hook::error::HookErrorKind as HEK;
use libimagstore::hook::result::HookResult;

generate_error_module!(
    generate_error_types!(GitHookError, GitHookErrorKind,
        ConfigError => "Configuration Error",
        NoConfigError => "No Configuration",
        ConfigTypeError => "Configuration value type wrong",
        RuntimeInformationSetupError => "Couldn't setup runtime information for git hook",
        RepositoryBackendError            => "Error in the git library",
        RepositoryError                   => "Error while interacting with git repository",
        RepositoryBranchError             => "Error while interacting with git branch(es)",
        RepositoryBranchNameFetchingError => "Error while fetching branch name",
        RepositorySignatureFetchingError  => "Error while fetching Authors/Committers signature",
        RepositoryIndexFetchingError      => "Error while fetching Repository Index",
        RepositoryIndexWritingError       => "Error while writing Repository Index",
        RepositoryPathAddingError         => "Error while adding Path to Index",
        RepositoryTreeWritingError        => "Error while writing repository tree",
        RepositoryTreeFindingError        => "Error while finding repository tree",
        RepositoryCommitFindingError      => "Error while finding commit",
        RepositoryCommittingError         => "Error while committing",
        RepositoryHeadFetchingError       => "Error while fetching HEAD",
        RepositoryHeadTargetFetchingError => "Error while fetching target of HEAD",
        HeadFetchError                    => "Error while getting HEAD",
        NotOnBranch                       => "No Branch is checked out",
        MkRepo => "Repository creation error",
        MkSignature => "Error while building Signature object",
        StoreIdHandlingError => "Error handling the store id object",
        StoreIdStripError => "Couldn't strip prefix from StoreID object",

        RepositoryFileStatusError => "Error while getting file status"
    );
);

impl GitHookError {

    pub fn inside_of<T>(self, h: HEK) -> HookResult<T> {
        Err(HE::new(h, Some(Box::new(self))))
    }

}

impl From<GitHookError> for HE {

    fn from(he: GitHookError) -> HE {
        HE::new(HEK::HookExecutionError, Some(Box::new(he)))
    }

}

impl From<Git2Error> for GitHookError {

    fn from(ge: Git2Error) -> GitHookError {
        GitHookError::new(GitHookErrorKind::RepositoryBackendError, Some(Box::new(ge)))
    }

}

pub trait MapIntoHookError<T> {
    fn map_into_hook_error(self) -> Result<T, HE>;
}

impl<T> MapIntoHookError<T> for Result<T, GitHookError> {

    fn map_into_hook_error(self) -> Result<T, HE> {
        self.map_err(|e| HE::new(HEK::HookExecutionError, Some(Box::new(e))))
    }

}

pub use self::error::GitHookError;
pub use self::error::GitHookErrorKind;
pub use self::error::MapErrInto;

<commit_msg>Add error kind for parent fetching error<commit_after>use git2::Error as Git2Error;

use libimagstore::hook::error::HookError as HE;
use libimagstore::hook::error::HookErrorKind as HEK;
use libimagstore::hook::result::HookResult;

generate_error_module!(
    generate_error_types!(GitHookError, GitHookErrorKind,
        ConfigError => "Configuration Error",
        NoConfigError => "No Configuration",
        ConfigTypeError => "Configuration value type wrong",
        RuntimeInformationSetupError => "Couldn't setup runtime information for git hook",
        RepositoryBackendError            => "Error in the git library",
        RepositoryError                   => "Error while interacting with git repository",
        RepositoryBranchError             => "Error while interacting with git branch(es)",
        RepositoryBranchNameFetchingError => "Error while fetching branch name",
        RepositorySignatureFetchingError  => "Error while fetching Authors/Committers signature",
        RepositoryIndexFetchingError      => "Error while fetching Repository Index",
        RepositoryIndexWritingError       => "Error while writing Repository Index",
        RepositoryPathAddingError         => "Error while adding Path to Index",
        RepositoryTreeWritingError        => "Error while writing repository tree",
        RepositoryTreeFindingError        => "Error while finding repository tree",
        RepositoryCommitFindingError      => "Error while finding commit",
        RepositoryCommittingError         => "Error while committing",
        RepositoryHeadFetchingError       => "Error while fetching HEAD",
        RepositoryHeadTargetFetchingError => "Error while fetching target of HEAD",
        RepositoryParentFetchingError     => "Error while fetching parent of commit",
        HeadFetchError                    => "Error while getting HEAD",
        NotOnBranch                       => "No Branch is checked out",
        MkRepo => "Repository creation error",
        MkSignature => "Error while building Signature object",
        StoreIdHandlingError => "Error handling the store id object",
        StoreIdStripError => "Couldn't strip prefix from StoreID object",

        RepositoryFileStatusError => "Error while getting file status"
    );
);

impl GitHookError {

    pub fn inside_of<T>(self, h: HEK) -> HookResult<T> {
        Err(HE::new(h, Some(Box::new(self))))
    }

}

impl From<GitHookError> for HE {

    fn from(he: GitHookError) -> HE {
        HE::new(HEK::HookExecutionError, Some(Box::new(he)))
    }

}

impl From<Git2Error> for GitHookError {

    fn from(ge: Git2Error) -> GitHookError {
        GitHookError::new(GitHookErrorKind::RepositoryBackendError, Some(Box::new(ge)))
    }

}

pub trait MapIntoHookError<T> {
    fn map_into_hook_error(self) -> Result<T, HE>;
}

impl<T> MapIntoHookError<T> for Result<T, GitHookError> {

    fn map_into_hook_error(self) -> Result<T, HE> {
        self.map_err(|e| HE::new(HEK::HookExecutionError, Some(Box::new(e))))
    }

}

pub use self::error::GitHookError;
pub use self::error::GitHookErrorKind;
pub use self::error::MapErrInto;

<|endoftext|>


<commit_before>pub const NODE: &'static str = "0";
pub const NYM: &'static str = "1";
pub const ATTRIB: &'static str = "100";
pub const SCHEMA: &'static str = "101";
pub const CLAIM_DEF: &'static str = "102";
pub const GET_ATTR: &'static str = "104";
pub const GET_NYM: &'static str = "105";
pub const GET_TXN: &'static str = "3";
pub const GET_SCHEMA: &'static str = "107";
pub const GET_CLAIM_DEF: &'static str = "108";
pub const GET_DDO: &'static str = "120";//TODO change number

pub const STEWARD: isize = 2;
pub const TRUSTEE: isize = 0;
pub const TRUST_ANCHOR: isize = 101;
pub const TGB = 100;
<commit_msg>IS-340: Corrected TGB constant declaration<commit_after>pub const NODE: &'static str = "0";
pub const NYM: &'static str = "1";
pub const ATTRIB: &'static str = "100";
pub const SCHEMA: &'static str = "101";
pub const CLAIM_DEF: &'static str = "102";
pub const GET_ATTR: &'static str = "104";
pub const GET_NYM: &'static str = "105";
pub const GET_TXN: &'static str = "3";
pub const GET_SCHEMA: &'static str = "107";
pub const GET_CLAIM_DEF: &'static str = "108";
pub const GET_DDO: &'static str = "120";//TODO change number

pub const STEWARD: isize = 2;
pub const TRUSTEE: isize = 0;
pub const TRUST_ANCHOR: isize = 101;
pub const TGB: isize = 100;
<|endoftext|>


<commit_before>// Copyright (c) 2016-2017 Chef Software Inc. and/or applicable contributors
//
// 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::{env,
          error,
          ffi,
          fmt,
          io,
          num,
          path::{self,
                 PathBuf},
          result};

use crate::{api_client,
            common,
            hcore,
            protocol::net,
            sup_client::SrvClientError};
use handlebars;
use toml;

pub type Result<T> = result::Result<T, Error>;

#[derive(Debug)]
#[allow(dead_code)]
pub enum Error {
    APIClient(api_client::Error),
    ArgumentError(&'static str),
    ButterflyError(String),
    CannotParseBinlinkBinaryName(PathBuf),
    CannotParseBinlinkSource(PathBuf),
    CannotRemoveDockerStudio,
    CannotRemoveFromChannel((String, String)),
    CannotRemovePackage(hcore::package::PackageIdent, usize),
    CommandNotFoundInPkg((String, String)),
    CryptoCLI(String),
    CtlClient(SrvClientError),
    DockerDaemonDown,
    DockerFileSharingNotEnabled,
    DockerImageNotFound(String),
    DockerNetworkDown(String),
    EnvJoinPathsError(env::JoinPathsError),
    ExecCommandNotFound(PathBuf),
    FFINulError(ffi::NulError),
    FileNotFound(String),
    HabitatCommon(common::Error),
    HabitatCore(hcore::Error),
    // Boxed because https://rust-lang-nursery.github.io/rust-clippy/master/index.html#large_enum_variant
    HandlebarsRenderError(Box<handlebars::TemplateRenderError>),
    IO(io::Error),
    JobGroupPromoteOrDemote(api_client::Error, bool /* promote */),
    JobGroupCancel(api_client::Error),
    JobGroupPromoteOrDemoteUnprocessable(bool /* promote */),
    NameLookup,
    NetErr(net::NetErr),
    PackageArchiveMalformed(String),
    ParseIntError(num::ParseIntError),
    PathPrefixError(path::StripPrefixError),
    ProvidesError(String),
    RemoteSupResolutionError(String, io::Error),
    RootRequired,
    ScheduleStatus(api_client::Error),
    SubcommandNotSupported(String),
    UnsupportedExportFormat(String),
    TomlDeserializeError(toml::de::Error),
    TomlSerializeError(toml::ser::Error),
    Utf8Error(String),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let msg = match *self {
            Error::APIClient(ref e) => e.to_string(),
            Error::ArgumentError(ref e) => e.to_string(),
            Error::ButterflyError(ref e) => e.to_string(),
            Error::CannotParseBinlinkBinaryName(ref p) => {
                format!("Cannot parse binlink binary name from {}.", p.display())
            }
            Error::CannotParseBinlinkSource(ref p) => {
                format!("Cannot parse binlink source path from {}.", p.display())
            }
            Error::CannotRemoveDockerStudio => {
                "Docker Studios are not persistent and cannot be removed".to_string()
            }
            Error::CannotRemoveFromChannel((ref p, ref c)) => {
                format!("{} cannot be removed from the {} channel.", p, c)
            }
            Error::CannotRemovePackage(ref p, ref c) => {
                format!("Can't remove package: {}. It is a dependency of {} packages",
                        p, c)
            }
            Error::CommandNotFoundInPkg((ref p, ref c)) => {
                format!("`{}' was not found under any 'PATH' directories in the {} package",
                        c, p)
            }
            Error::CryptoCLI(ref e) => e.to_string(),
            Error::CtlClient(ref e) => e.to_string(),
            Error::DockerDaemonDown => {
                "Can not connect to Docker. Is the Docker daemon running?".to_string()
            }
            #[cfg(not(windows))]
            Error::DockerFileSharingNotEnabled => {
                "File Sharing must be enabled in order to enter a studio.\nPlease enable it in the \
                 Docker preferences and share (at a minimum) your home directory."
                                                                                .to_string()
            }
            #[cfg(windows)]
            Error::DockerFileSharingNotEnabled => {
                "File Sharing must be enabled in order to enter a studio.\nPlease select a drive \
                 to share in the Docker preferences."
                                                     .to_string()
            }
            Error::DockerImageNotFound(ref e) => {
                format!("The Docker image {} was not found in the docker registry.\nYou can \
                         specify your own Docker image using the HAB_DOCKER_STUDIO_IMAGE \
                         environment variable.",
                        e)
            }
            Error::DockerNetworkDown(ref e) => {
                format!("The Docker image {} is unreachable due to a network error.\nThe image \
                         must be reachable to ensure the versions of hab inside and outside the \
                         studio match.\nYou can specify your own Docker image using the \
                         HAB_DOCKER_STUDIO_IMAGE environment variable.",
                        e)
            }
            Error::EnvJoinPathsError(ref err) => format!("{}", err),
            Error::ExecCommandNotFound(ref c) => {
                format!("`{}' was not found on the filesystem or in PATH",
                        c.display())
            }
            Error::FFINulError(ref e) => e.to_string(),
            Error::FileNotFound(ref e) => format!("File not found at: {}", e),
            Error::HabitatCommon(ref e) => e.to_string(),
            Error::HabitatCore(ref e) => e.to_string(),
            Error::HandlebarsRenderError(ref e) => e.to_string(),
            Error::IO(ref err) => format!("{}", err),
            Error::JobGroupPromoteOrDemoteUnprocessable(true) => {
                "Failed to promote job group, the build job is still in progress".to_string()
            }
            Error::JobGroupPromoteOrDemoteUnprocessable(false) => {
                "Failed to demote job group, the build job is still in progress".to_string()
            }
            Error::JobGroupPromoteOrDemote(ref e, promote) => {
                format!("Failed to {} job group: {:?}",
                        if promote { "promote" } else { "demote" },
                        e)
            }
            Error::JobGroupCancel(ref e) => format!("Failed to cancel job group: {:?}", e),
            Error::NameLookup => "Error resolving a name or IP address".to_string(),
            Error::NetErr(ref e) => e.to_string(),
            Error::PackageArchiveMalformed(ref e) => {
                format!("Package archive was unreadable or contained unexpected contents: {:?}",
                        e)
            }
            Error::ParseIntError(ref err) => format!("{}", err),
            Error::PathPrefixError(ref err) => format!("{}", err),
            Error::ProvidesError(ref err) => format!("Can't find {}", err),
            Error::RemoteSupResolutionError(ref sup_addr, ref err) => {
                format!("Failed to resolve remote supervisor '{}': {}",
                        sup_addr, err,)
            }
            Error::RootRequired => {
                "Root or administrator permissions required to complete operation".to_string()
            }
            Error::ScheduleStatus(ref e) => format!("Failed to retrieve job group status: {:?}", e),
            Error::SubcommandNotSupported(ref e) => {
                format!("Subcommand `{}' not supported on this operating system", e)
            }
            Error::UnsupportedExportFormat(ref e) => format!("Unsupported export format: {}", e),
            Error::TomlDeserializeError(ref e) => format!("Can't deserialize TOML: {}", e),
            Error::TomlSerializeError(ref e) => format!("Can't serialize TOML: {}", e),
            Error::Utf8Error(ref e) => format!("Error processing a string as UTF-8: {}", e),
        };
        write!(f, "{}", msg)
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::APIClient(ref err) => err.description(),
            Error::ArgumentError(_) => "There was an error parsing an error or with it's value",
            Error::ButterflyError(_) => "Butterfly has had an error",
            Error::CannotParseBinlinkBinaryName(_) => "Cannot parse binlink binary name",
            Error::CannotParseBinlinkSource(_) => "Cannot parse binlink source path",
            Error::CannotRemoveFromChannel(_) => {
                "Package cannot be removed from the specified channel"
            }
            Error::CannotRemoveDockerStudio => {
                "Docker Studios are not persistent and cannot be removed"
            }
            Error::CannotRemovePackage(..) => {
                "A package can only be removed if it is not a dependency of any other package"
            }
            Error::CommandNotFoundInPkg(_) => {
                "Command was not found under any 'PATH' directories in the package"
            }
            Error::CryptoCLI(_) => "A cryptographic error has occurred",
            Error::CtlClient(ref err) => err.description(),
            Error::DockerDaemonDown => "The Docker daemon could not be found.",
            Error::DockerFileSharingNotEnabled => "Docker file sharing is not enabled.",
            Error::DockerImageNotFound(_) => "The Docker image was not found.",
            Error::DockerNetworkDown(_) => "The Docker registry is unreachable.",
            Error::EnvJoinPathsError(ref err) => err.description(),
            Error::ExecCommandNotFound(_) => "Exec command was not found on filesystem or in PATH",
            Error::FFINulError(ref err) => err.description(),
            Error::FileNotFound(_) => "File not found",
            Error::HabitatCommon(ref err) => err.description(),
            Error::HabitatCore(ref err) => err.description(),
            Error::HandlebarsRenderError(ref err) => err.description(),
            Error::IO(ref err) => err.description(),
            Error::JobGroupPromoteOrDemoteUnprocessable(true) => {
                "Failed to promote job group, the build job is still in progress"
            }
            Error::JobGroupPromoteOrDemoteUnprocessable(false) => {
                "Failed to demote job group, the build job is still in progress"
            }
            Error::JobGroupPromoteOrDemote(ref err, _) => err.description(),
            Error::JobGroupCancel(ref err) => err.description(),
            Error::NetErr(ref err) => err.description(),
            Error::NameLookup => "Error resolving a name or IP address",
            Error::PackageArchiveMalformed(_) => {
                "Package archive was unreadable or had unexpected contents"
            }
            Error::ParseIntError(ref err) => err.description(),
            Error::PathPrefixError(ref err) => err.description(),
            Error::ProvidesError(_) => {
                "Can't find a package that provides the given search parameter"
            }
            Error::RemoteSupResolutionError(_, ref err) => err.description(),
            Error::RootRequired => {
                "Root or administrator permissions required to complete operation"
            }
            Error::ScheduleStatus(ref err) => err.description(),
            Error::SubcommandNotSupported(_) => "Subcommand not supported on this operating system",
            Error::UnsupportedExportFormat(_) => "Unsupported export format",
            Error::TomlDeserializeError(_) => "Can't deserialize TOML",
            Error::TomlSerializeError(_) => "Can't serialize TOML",
            Error::Utf8Error(_) => "Error processing string as UTF-8",
        }
    }
}

impl From<api_client::Error> for Error {
    fn from(err: api_client::Error) -> Error { Error::APIClient(err) }
}

impl From<common::Error> for Error {
    fn from(err: common::Error) -> Error { Error::HabitatCommon(err) }
}

impl From<ffi::NulError> for Error {
    fn from(err: ffi::NulError) -> Error { Error::FFINulError(err) }
}

impl From<hcore::Error> for Error {
    fn from(err: hcore::Error) -> Error { Error::HabitatCore(err) }
}

impl From<handlebars::TemplateRenderError> for Error {
    fn from(err: handlebars::TemplateRenderError) -> Error {
        Error::HandlebarsRenderError(Box::new(err))
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error { Error::IO(err) }
}

impl From<path::StripPrefixError> for Error {
    fn from(err: path::StripPrefixError) -> Error { Error::PathPrefixError(err) }
}

impl From<toml::de::Error> for Error {
    fn from(err: toml::de::Error) -> Self { Error::TomlDeserializeError(err) }
}
impl From<toml::ser::Error> for Error {
    fn from(err: toml::ser::Error) -> Self { Error::TomlSerializeError(err) }
}

impl From<env::JoinPathsError> for Error {
    fn from(err: env::JoinPathsError) -> Self { Error::EnvJoinPathsError(err) }
}

impl From<SrvClientError> for Error {
    fn from(err: SrvClientError) -> Self { Error::CtlClient(err) }
}

impl From<net::NetErr> for Error {
    fn from(err: net::NetErr) -> Self { Error::NetErr(err) }
}
<commit_msg>First pass at adding Error type for serde_json::Error<commit_after>// Copyright (c) 2016-2017 Chef Software Inc. and/or applicable contributors
//
// 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::{env,
          error,
          ffi,
          fmt,
          io,
          num,
          path::{self,
                 PathBuf},
          result};

use crate::{api_client,
            common,
            hcore,
            protocol::net,
            sup_client::SrvClientError};
use handlebars;
use toml;

pub type Result<T> = result::Result<T, Error>;

#[derive(Debug)]
#[allow(dead_code)]
pub enum Error {
    APIClient(api_client::Error),
    ArgumentError(&'static str),
    ButterflyError(String),
    CannotParseBinlinkBinaryName(PathBuf),
    CannotParseBinlinkSource(PathBuf),
    CannotRemoveDockerStudio,
    CannotRemoveFromChannel((String, String)),
    CannotRemovePackage(hcore::package::PackageIdent, usize),
    CommandNotFoundInPkg((String, String)),
    CryptoCLI(String),
    CtlClient(SrvClientError),
    DockerDaemonDown,
    DockerFileSharingNotEnabled,
    DockerImageNotFound(String),
    DockerNetworkDown(String),
    EnvJoinPathsError(env::JoinPathsError),
    ExecCommandNotFound(PathBuf),
    FFINulError(ffi::NulError),
    FileNotFound(String),
    HabitatCommon(common::Error),
    HabitatCore(hcore::Error),
    // Boxed because https://rust-lang-nursery.github.io/rust-clippy/master/index.html#large_enum_variant
    HandlebarsRenderError(Box<handlebars::TemplateRenderError>),
    IO(io::Error),
    JobGroupPromoteOrDemote(api_client::Error, bool /* promote */),
    JobGroupCancel(api_client::Error),
    JobGroupPromoteOrDemoteUnprocessable(bool /* promote */),
    JsonErr(serde_json::Error),
    NameLookup,
    NetErr(net::NetErr),
    PackageArchiveMalformed(String),
    ParseIntError(num::ParseIntError),
    PathPrefixError(path::StripPrefixError),
    ProvidesError(String),
    RemoteSupResolutionError(String, io::Error),
    RootRequired,
    ScheduleStatus(api_client::Error),
    SubcommandNotSupported(String),
    UnsupportedExportFormat(String),
    TomlDeserializeError(toml::de::Error),
    TomlSerializeError(toml::ser::Error),
    Utf8Error(String),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let msg = match *self {
            Error::APIClient(ref e) => e.to_string(),
            Error::ArgumentError(ref e) => e.to_string(),
            Error::ButterflyError(ref e) => e.to_string(),
            Error::CannotParseBinlinkBinaryName(ref p) => {
                format!("Cannot parse binlink binary name from {}.", p.display())
            }
            Error::CannotParseBinlinkSource(ref p) => {
                format!("Cannot parse binlink source path from {}.", p.display())
            }
            Error::CannotRemoveDockerStudio => {
                "Docker Studios are not persistent and cannot be removed".to_string()
            }
            Error::CannotRemoveFromChannel((ref p, ref c)) => {
                format!("{} cannot be removed from the {} channel.", p, c)
            }
            Error::CannotRemovePackage(ref p, ref c) => {
                format!("Can't remove package: {}. It is a dependency of {} packages",
                        p, c)
            }
            Error::CommandNotFoundInPkg((ref p, ref c)) => {
                format!("`{}' was not found under any 'PATH' directories in the {} package",
                        c, p)
            }
            Error::CryptoCLI(ref e) => e.to_string(),
            Error::CtlClient(ref e) => e.to_string(),
            Error::DockerDaemonDown => {
                "Can not connect to Docker. Is the Docker daemon running?".to_string()
            }
            #[cfg(not(windows))]
            Error::DockerFileSharingNotEnabled => {
                "File Sharing must be enabled in order to enter a studio.\nPlease enable it in the \
                 Docker preferences and share (at a minimum) your home directory."
                                                                                .to_string()
            }
            #[cfg(windows)]
            Error::DockerFileSharingNotEnabled => {
                "File Sharing must be enabled in order to enter a studio.\nPlease select a drive \
                 to share in the Docker preferences."
                                                     .to_string()
            }
            Error::DockerImageNotFound(ref e) => {
                format!("The Docker image {} was not found in the docker registry.\nYou can \
                         specify your own Docker image using the HAB_DOCKER_STUDIO_IMAGE \
                         environment variable.",
                        e)
            }
            Error::DockerNetworkDown(ref e) => {
                format!("The Docker image {} is unreachable due to a network error.\nThe image \
                         must be reachable to ensure the versions of hab inside and outside the \
                         studio match.\nYou can specify your own Docker image using the \
                         HAB_DOCKER_STUDIO_IMAGE environment variable.",
                        e)
            }
            Error::EnvJoinPathsError(ref err) => format!("{}", err),
            Error::ExecCommandNotFound(ref c) => {
                format!("`{}' was not found on the filesystem or in PATH",
                        c.display())
            }
            Error::FFINulError(ref e) => e.to_string(),
            Error::FileNotFound(ref e) => format!("File not found at: {}", e),
            Error::HabitatCommon(ref e) => e.to_string(),
            Error::HabitatCore(ref e) => e.to_string(),
            Error::HandlebarsRenderError(ref e) => e.to_string(),
            Error::IO(ref err) => format!("{}", err),
            Error::JobGroupPromoteOrDemoteUnprocessable(true) => {
                "Failed to promote job group, the build job is still in progress".to_string()
            }
            Error::JobGroupPromoteOrDemoteUnprocessable(false) => {
                "Failed to demote job group, the build job is still in progress".to_string()
            }
            Error::JobGroupPromoteOrDemote(ref e, promote) => {
                format!("Failed to {} job group: {:?}",
                        if promote { "promote" } else { "demote" },
                        e)
            }
            Error::JsonErr(ref e) => e.to_string(),
            Error::JobGroupCancel(ref e) => format!("Failed to cancel job group: {:?}", e),
            Error::NameLookup => "Error resolving a name or IP address".to_string(),
            Error::NetErr(ref e) => e.to_string(),
            Error::PackageArchiveMalformed(ref e) => {
                format!("Package archive was unreadable or contained unexpected contents: {:?}",
                        e)
            }
            Error::ParseIntError(ref err) => format!("{}", err),
            Error::PathPrefixError(ref err) => format!("{}", err),
            Error::ProvidesError(ref err) => format!("Can't find {}", err),
            Error::RemoteSupResolutionError(ref sup_addr, ref err) => {
                format!("Failed to resolve remote supervisor '{}': {}",
                        sup_addr, err,)
            }
            Error::RootRequired => {
                "Root or administrator permissions required to complete operation".to_string()
            }
            Error::ScheduleStatus(ref e) => format!("Failed to retrieve job group status: {:?}", e),
            Error::SubcommandNotSupported(ref e) => {
                format!("Subcommand `{}' not supported on this operating system", e)
            }
            Error::UnsupportedExportFormat(ref e) => format!("Unsupported export format: {}", e),
            Error::TomlDeserializeError(ref e) => format!("Can't deserialize TOML: {}", e),
            Error::TomlSerializeError(ref e) => format!("Can't serialize TOML: {}", e),
            Error::Utf8Error(ref e) => format!("Error processing a string as UTF-8: {}", e),
        };
        write!(f, "{}", msg)
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::APIClient(ref err) => err.description(),
            Error::ArgumentError(_) => "There was an error parsing an error or with it's value",
            Error::ButterflyError(_) => "Butterfly has had an error",
            Error::CannotParseBinlinkBinaryName(_) => "Cannot parse binlink binary name",
            Error::CannotParseBinlinkSource(_) => "Cannot parse binlink source path",
            Error::CannotRemoveFromChannel(_) => {
                "Package cannot be removed from the specified channel"
            }
            Error::CannotRemoveDockerStudio => {
                "Docker Studios are not persistent and cannot be removed"
            }
            Error::CannotRemovePackage(..) => {
                "A package can only be removed if it is not a dependency of any other package"
            }
            Error::CommandNotFoundInPkg(_) => {
                "Command was not found under any 'PATH' directories in the package"
            }
            Error::CryptoCLI(_) => "A cryptographic error has occurred",
            Error::CtlClient(ref err) => err.description(),
            Error::DockerDaemonDown => "The Docker daemon could not be found.",
            Error::DockerFileSharingNotEnabled => "Docker file sharing is not enabled.",
            Error::DockerImageNotFound(_) => "The Docker image was not found.",
            Error::DockerNetworkDown(_) => "The Docker registry is unreachable.",
            Error::EnvJoinPathsError(ref err) => err.description(),
            Error::ExecCommandNotFound(_) => "Exec command was not found on filesystem or in PATH",
            Error::FFINulError(ref err) => err.description(),
            Error::FileNotFound(_) => "File not found",
            Error::HabitatCommon(ref err) => err.description(),
            Error::HabitatCore(ref err) => err.description(),
            Error::HandlebarsRenderError(ref err) => err.description(),
            Error::IO(ref err) => err.description(),
            Error::JobGroupPromoteOrDemoteUnprocessable(true) => {
                "Failed to promote job group, the build job is still in progress"
            }
            Error::JobGroupPromoteOrDemoteUnprocessable(false) => {
                "Failed to demote job group, the build job is still in progress"
            }
            Error::JobGroupPromoteOrDemote(ref err, _) => err.description(),
            Error::JobGroupCancel(ref err) => err.description(),
            Error::NetErr(ref err) => err.description(),
            Error::NameLookup => "Error resolving a name or IP address",
            Error::PackageArchiveMalformed(_) => {
                "Package archive was unreadable or had unexpected contents"
            }
            Error::ParseIntError(ref err) => err.description(),
            Error::PathPrefixError(ref err) => err.description(),
            Error::ProvidesError(_) => {
                "Can't find a package that provides the given search parameter"
            }
            Error::JsonErr(ref err) => err.description(),
            Error::RemoteSupResolutionError(_, ref err) => err.description(),
            Error::RootRequired => {
                "Root or administrator permissions required to complete operation"
            }
            Error::ScheduleStatus(ref err) => err.description(),
            Error::SubcommandNotSupported(_) => "Subcommand not supported on this operating system",
            Error::UnsupportedExportFormat(_) => "Unsupported export format",
            Error::TomlDeserializeError(_) => "Can't deserialize TOML",
            Error::TomlSerializeError(_) => "Can't serialize TOML",
            Error::Utf8Error(_) => "Error processing string as UTF-8",
        }
    }
}

impl From<api_client::Error> for Error {
    fn from(err: api_client::Error) -> Error { Error::APIClient(err) }
}

impl From<common::Error> for Error {
    fn from(err: common::Error) -> Error { Error::HabitatCommon(err) }
}

impl From<ffi::NulError> for Error {
    fn from(err: ffi::NulError) -> Error { Error::FFINulError(err) }
}

impl From<hcore::Error> for Error {
    fn from(err: hcore::Error) -> Error { Error::HabitatCore(err) }
}

impl From<handlebars::TemplateRenderError> for Error {
    fn from(err: handlebars::TemplateRenderError) -> Error {
        Error::HandlebarsRenderError(Box::new(err))
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error { Error::IO(err) }
}

impl From<path::StripPrefixError> for Error {
    fn from(err: path::StripPrefixError) -> Error { Error::PathPrefixError(err) }
}

impl From<toml::de::Error> for Error {
    fn from(err: toml::de::Error) -> Self { Error::TomlDeserializeError(err) }
}
impl From<toml::ser::Error> for Error {
    fn from(err: toml::ser::Error) -> Self { Error::TomlSerializeError(err) }
}

impl From<env::JoinPathsError> for Error {
    fn from(err: env::JoinPathsError) -> Self { Error::EnvJoinPathsError(err) }
}

impl From<SrvClientError> for Error {
    fn from(err: SrvClientError) -> Self { Error::CtlClient(err) }
}

impl From<net::NetErr> for Error {
    fn from(err: net::NetErr) -> Self { Error::NetErr(err) }
}

impl From<serde_json::Error> for Error {
    fn from(err: serde_json::Error) -> Self {
        Error::JsonErr(err)
    }
}
<|endoftext|>


<commit_before>use platform::io;
use core::kinds::Copy;

pub enum Color {
    Black = 0,
    Blue = 1,
    Green = 2,
    Cyan = 3,
    Red = 4,
    Pink = 5,
    Brown = 6,
    LightGray = 7,
    DarkGray = 8,
    LightBlue = 9,
    LightGreen = 10,
    LightCyan = 11,
    LightRed = 12,
    LightPink = 13,
    Yellow = 14,
    White = 15,
}

impl Copy for Color {}

pub static ROWS: uint = 25;
pub static COLS: uint = 80;

pub fn putc(xpos: uint, ypos: uint, value: u8)
{
	if xpos >= COLS || ypos >= ROWS { return }
	unsafe
	{
		*((0xb8000 + ypos * COLS * 2 + xpos * 2) as *mut u8) = value;
	}
}

pub fn setfg(xpos: uint, ypos: uint, value: Color)
{
	if xpos >= COLS || ypos >= ROWS { return }
	unsafe
	{
		let ptr = (0xb8000 + ypos * COLS * 2 + xpos * 2 + 1) as *mut u8;
		*ptr = (*ptr & 0xF0) | (value as u8 & 0x0F);
	}
}

pub fn setbg(xpos: uint, ypos: uint, value: Color)
{
	if xpos >= COLS || ypos >= ROWS { return }
	unsafe
	{
		let ptr = (0xb8000 + ypos * COLS * 2 + xpos * 2 + 1) as *mut u8;
		*ptr = (*ptr & 0x0F) | ((value as u8 << 4) & 0x70);
	}
}

pub fn move_cursor(xpos: uint, ypos: uint)
{
	if xpos >= COLS || ypos >= COLS { return };
	let pos = ypos * COLS + xpos;
	unsafe
	{
		io::outport(0x3D4, 14);
		io::outport(0x3D5, (pos >> 8) as u8);
		io::outport(0x3D4, 15);
		io::outport(0x3D5, pos as u8);
	}
}
<commit_msg>Fix parsing error<commit_after>use platform::io;
use core::kinds::Copy;

pub enum Color {
    Black = 0,
    Blue = 1,
    Green = 2,
    Cyan = 3,
    Red = 4,
    Pink = 5,
    Brown = 6,
    LightGray = 7,
    DarkGray = 8,
    LightBlue = 9,
    LightGreen = 10,
    LightCyan = 11,
    LightRed = 12,
    LightPink = 13,
    Yellow = 14,
    White = 15,
}

impl Copy for Color {}

pub static ROWS: uint = 25;
pub static COLS: uint = 80;

pub fn putc(xpos: uint, ypos: uint, value: u8)
{
	if xpos >= COLS || ypos >= ROWS { return }
	unsafe
	{
		*((0xb8000 + ypos * COLS * 2 + xpos * 2) as *mut u8) = value;
	}
}

pub fn setfg(xpos: uint, ypos: uint, value: Color)
{
	if xpos >= COLS || ypos >= ROWS { return }
	unsafe
	{
		let ptr = (0xb8000 + ypos * COLS * 2 + xpos * 2 + 1) as *mut u8;
		*ptr = (*ptr & 0xF0) | (value as u8 & 0x0F);
	}
}

pub fn setbg(xpos: uint, ypos: uint, value: Color)
{
	if xpos >= COLS || ypos >= ROWS { return }
	unsafe
	{
		let ptr = (0xb8000 + ypos * COLS * 2 + xpos * 2 + 1) as *mut u8;
		*ptr = (*ptr & 0x0F) | (((value as u8) << 4) & 0x70);
	}
}

pub fn move_cursor(xpos: uint, ypos: uint)
{
	if xpos >= COLS || ypos >= COLS { return };
	let pos = ypos * COLS + xpos;
	unsafe
	{
		io::outport(0x3D4, 14);
		io::outport(0x3D5, (pos >> 8) as u8);
		io::outport(0x3D4, 15);
		io::outport(0x3D5, pos as u8);
	}
}
<|endoftext|>


<commit_before>
// Delete all of this eventually

use std::f64::consts::PI;
use ship::{Attach, Beam, Part, Structure};
use tagtree;

pub fn simple_ship() -> Structure {

    let (forward, reverse, left, right) = (0,1,2,3);
    let attitude_attach = Attach { location: 10.0, rotation: 0.0 };

    let engine_l = box part!(engine!(4.0, 4.0, left));
    let attitude_l = beam!(10.0, vec!((attitude_attach.clone(), engine_l)));

    let engine_r = box part!(engine!(4.0, 4.0, right));
    let attitude_r = beam!(10.0, vec!((attitude_attach, engine_r)));

    let engine_rev = box part!(engine!(4.0, 4.0, reverse));
    let rev_l_attach = Attach { location: 10.0, rotation: -PI };
    let rev_l = beam!(10.0, vec!((rev_l_attach, engine_rev)));

    let engine_rev = box part!(engine!(4.0, 4.0, reverse));
    let rev_r_attach = Attach { location: 10.0, rotation: PI };
    let rev_r = beam!(10.0, vec!((rev_r_attach, engine_rev)));

    let mods = vec!(
        attach_tree!(6.0, 3.0 * PI / 2.0, rev_l),
        (Attach { location: 6.0, rotation: PI / 2.0}, box rev_r),
        (Attach { location: 42.0, rotation: 3.0 * PI / 2.0 }, box attitude_l),
        (Attach { location: 42.0, rotation: PI / 2.0}, box attitude_r),
		attach_part!(0.0, 0.0, vessel!(7.0, 7.0)),
        (Attach { location: 25.0, rotation: 0.0}, box part!(fuel_tank!(14.0, 30.0))),
        (Attach { location: 50.0, rotation: 0.0}, box part!(engine!(13.0, 13.0, forward)))
        );

    beam!(50.0, mods)
}
<commit_msg>more macro conversion<commit_after>
// Delete all of this eventually

use std::f64::consts::PI;
use ship::{Attach, Beam, Part, Structure};
use tagtree;

// TODO can further simplify with the builder macros

pub fn simple_ship() -> Structure {

    let (forward, reverse, left, right) = (0,1,2,3);
    let attitude_attach = Attach { location: 10.0, rotation: 0.0 };

    let engine_l = box part!(engine!(4.0, 4.0, left));
    let attitude_l = beam!(10.0, vec!((attitude_attach.clone(), engine_l)));

    let engine_r = box part!(engine!(4.0, 4.0, right));
    let attitude_r = beam!(10.0, vec!((attitude_attach, engine_r)));

    let engine_rev = box part!(engine!(4.0, 4.0, reverse));
    let rev_l_attach = Attach { location: 10.0, rotation: -PI };
    let rev_l = beam!(10.0, vec!((rev_l_attach, engine_rev)));

    let engine_rev = box part!(engine!(4.0, 4.0, reverse));
    let rev_r_attach = Attach { location: 10.0, rotation: PI };
    let rev_r = beam!(10.0, vec!((rev_r_attach, engine_rev)));

    let mods = vec!(
        attach_tree!(6.0, 3.0 * PI / 2.0, rev_l),
        attach_tree!(6.0, PI / 2.0, rev_r),
        attach_tree!(42.0, 3.0 * PI / 2.0, attitude_l),
        attach_tree!(42.0, PI / 2.0, attitude_r),
        attach_part!(0.0, 0.0, vessel!(7.0, 7.0)),
        attach_part!(25.0, 0.0, fuel_tank!(14.0, 30.0)),
        attach_part!(50.0, 0.0, engine!(13.0, 13.0, forward)),
        );

    beam!(50.0, mods)
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use heartbeats_simple::HeartbeatPow as Heartbeat;
use heartbeats_simple::HeartbeatPowContext as HeartbeatContext;
use profile_traits::time::ProfilerCategory;
use servo_config::opts;
use std::collections::HashMap;
use std::env::var_os;
use std::error::Error;
use std::fs::File;
use std::mem;
use std::path::Path;

static mut HBS: Option<*mut HashMap<ProfilerCategory, Heartbeat>> = None;

/// Initialize heartbeats
pub fn init() {
    let mut hbs: HashMap<ProfilerCategory, Heartbeat> = HashMap::new();
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::Compositing);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutPerform);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutStyleRecalc);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutTextShaping);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutRestyleDamagePropagation);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutNonIncrementalReset);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutSelectorMatch);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutTreeBuilder);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutDamagePropagate);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutGeneratedContent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutDisplayListSorting);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutFloatPlacementSpeculation);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutMain);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutStoreOverflow);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutParallelWarmup);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::LayoutDispListBuild);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::NetHTTPRequestResponse);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::PaintingPerTile);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::PaintingPrepBuff);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::Painting);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ImageDecoding);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ImageSaving);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptAttachLayout);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptConstellationMsg);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptDevtoolsMsg);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptDocumentEvent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptDomEvent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptEvaluate);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptEvent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptFileRead);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptImageCacheMsg);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptInputEvent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptNetworkEvent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptParseHTML);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptPlannedNavigation);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptResize);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptSetScrollState);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptSetViewport);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptTimerEvent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptStylesheetLoad);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptUpdateReplacedElement);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptWebSocketEvent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptWorkerEvent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptServiceWorkerEvent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptParseXML);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptEnterFullscreen);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptExitFullscreen);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ScriptWebVREvent);
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ApplicationHeartbeat);
    unsafe {
        HBS = Some(mem::transmute(Box::new(hbs)));
    }
}

/// Log regmaining buffer data and cleanup heartbeats
pub fn cleanup() {
    unsafe {
        if let Some(hbs) = HBS {
            let mut h: Box<HashMap<ProfilerCategory, Heartbeat>> = mem::transmute(hbs);
            for (_, mut v) in h.iter_mut() {
                // log any remaining heartbeat records before dropping
                log_heartbeat_records(v);
            }
            h.clear();
        }
        HBS = None;
    }
}

/// Check if a heartbeat exists for the given category
pub fn is_heartbeat_enabled(category: &ProfilerCategory) -> bool {
    unsafe {
        HBS.map_or(false, |m| (*m).contains_key(category))
    }
}

/// Issue a heartbeat (if one exists) for the given category
pub fn maybe_heartbeat(category: &ProfilerCategory,
                       start_time: u64,
                       end_time: u64,
                       start_energy: u64,
                       end_energy: u64) {
    unsafe {
        if let Some(map) = HBS {
            if let Some(mut h) = (*map).get_mut(category) {
                (*h).heartbeat(0, 1, start_time, end_time, start_energy, end_energy);
            }
        }
    }
}

// TODO(cimes): Android doesn't really do environment variables. Need a better way to configure dynamically.

fn is_create_heartbeat(category: &ProfilerCategory) -> bool {
    opts::get().profile_heartbeats || var_os(format!("SERVO_HEARTBEAT_ENABLE_{:?}", category)).is_some()
}

fn open_heartbeat_log<P: AsRef<Path>>(name: P) -> Option<File> {
    match File::create(name) {
        Ok(f) => Some(f),
        Err(e) => {
            warn!("Failed to open heartbeat log: {}", Error::description(&e));
            None
        },
    }
}

#[cfg(target_os = "android")]
fn get_heartbeat_log(category: &ProfilerCategory) -> Option<File> {
    open_heartbeat_log(format!("/sdcard/servo/heartbeat-{:?}.log", category))
}

#[cfg(not(target_os = "android"))]
fn get_heartbeat_log(category: &ProfilerCategory) -> Option<File> {
    var_os(format!("SERVO_HEARTBEAT_LOG_{:?}", category)).and_then(|name| open_heartbeat_log(&name))
}

fn get_heartbeat_window_size(category: &ProfilerCategory) -> usize {
    const WINDOW_SIZE_DEFAULT: usize = 1;
    match var_os(format!("SERVO_HEARTBEAT_WINDOW_{:?}", category)) {
        Some(w) => match w.into_string() {
            Ok(s) => s.parse::<usize>().unwrap_or(WINDOW_SIZE_DEFAULT),
            _ => WINDOW_SIZE_DEFAULT,
        },
        None => WINDOW_SIZE_DEFAULT,
    }
}

/// Possibly create a heartbeat
fn maybe_create_heartbeat(hbs: &mut HashMap<ProfilerCategory, Heartbeat>,
                          category: ProfilerCategory) {
    if is_create_heartbeat(&category) {
        // get optional log file
        let logfile: Option<File> = get_heartbeat_log(&category);
        // window size
        let window_size: usize = get_heartbeat_window_size(&category);
        // create the heartbeat
        match Heartbeat::new(window_size, Some(heartbeat_window_callback), logfile) {
            Ok(hb) => {
                debug!("Created heartbeat for {:?}", category);
                hbs.insert(category, hb);
            },
            Err(e) => warn!("Failed to create heartbeat for {:?}: {}", category, e),
        }
    };
}

/// Log heartbeat records up to the buffer index
fn log_heartbeat_records(hb: &mut Heartbeat) {
    match hb.log_to_buffer_index() {
        Ok(_) => (),
        Err(e) => warn!("Failed to write heartbeat log: {}", Error::description(&e)),
    }
}

/// Callback function used to log the window buffer.
/// When this is called from native C, the heartbeat is safely locked
extern fn heartbeat_window_callback(hb: *const HeartbeatContext) {
    unsafe {
        if let Some(map) = HBS {
            for (_, v) in (*map).iter_mut() {
                if &v.hb as *const HeartbeatContext == hb {
                    log_heartbeat_records(v);
                }
            }
        }
    }
}
<commit_msg>Create heartbeats dynamically as needed - avoids the need for hardcoding and maintaining heartbeats for profiler categories. Use consistent variable names. Use Box::into_raw and Box::from_raw instead of std::mem::transmute.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use heartbeats_simple::HeartbeatPow as Heartbeat;
use heartbeats_simple::HeartbeatPowContext as HeartbeatContext;
use profile_traits::time::ProfilerCategory;
use servo_config::opts;
use std::collections::HashMap;
use std::env::var_os;
use std::error::Error;
use std::fs::File;
use std::path::Path;

static mut HBS: Option<*mut HashMap<ProfilerCategory, Heartbeat>> = None;

/// Initialize heartbeats
pub fn init() {
    let mut hbs: Box<HashMap<ProfilerCategory, Heartbeat>> = Box::new(HashMap::new());
    maybe_create_heartbeat(&mut hbs, ProfilerCategory::ApplicationHeartbeat);
    unsafe {
        HBS = Some(Box::into_raw(hbs));
    }
}

/// Log regmaining buffer data and cleanup heartbeats
pub fn cleanup() {
    unsafe {
        if let Some(hbs_ptr) = HBS {
            let mut hbs: Box<HashMap<ProfilerCategory, Heartbeat>> = Box::from_raw(hbs_ptr);
            for (_, mut v) in hbs.iter_mut() {
                // log any remaining heartbeat records before dropping
                log_heartbeat_records(v);
            }
            hbs.clear();
        }
        HBS = None;
    }
}

/// Check if a heartbeat exists for the given category
pub fn is_heartbeat_enabled(category: &ProfilerCategory) -> bool {
    unsafe {
        HBS.map_or(false, |hbs_ptr| (*hbs_ptr).contains_key(category) || is_create_heartbeat(category))
    }
}

/// Issue a heartbeat (if one exists) for the given category
pub fn maybe_heartbeat(category: &ProfilerCategory,
                       start_time: u64,
                       end_time: u64,
                       start_energy: u64,
                       end_energy: u64) {
    unsafe {
        if let Some(hbs_ptr) = HBS {
            if !(*hbs_ptr).contains_key(category) {
                maybe_create_heartbeat(&mut (*hbs_ptr), category.clone());
            }
            if let Some(mut h) = (*hbs_ptr).get_mut(category) {
                (*h).heartbeat(0, 1, start_time, end_time, start_energy, end_energy);
            }
        }
    }
}

// TODO(cimes): Android doesn't really do environment variables. Need a better way to configure dynamically.

fn is_create_heartbeat(category: &ProfilerCategory) -> bool {
    opts::get().profile_heartbeats || var_os(format!("SERVO_HEARTBEAT_ENABLE_{:?}", category)).is_some()
}

fn open_heartbeat_log<P: AsRef<Path>>(name: P) -> Option<File> {
    match File::create(name) {
        Ok(f) => Some(f),
        Err(e) => {
            warn!("Failed to open heartbeat log: {}", Error::description(&e));
            None
        },
    }
}

#[cfg(target_os = "android")]
fn get_heartbeat_log(category: &ProfilerCategory) -> Option<File> {
    open_heartbeat_log(format!("/sdcard/servo/heartbeat-{:?}.log", category))
}

#[cfg(not(target_os = "android"))]
fn get_heartbeat_log(category: &ProfilerCategory) -> Option<File> {
    var_os(format!("SERVO_HEARTBEAT_LOG_{:?}", category)).and_then(|name| open_heartbeat_log(&name))
}

fn get_heartbeat_window_size(category: &ProfilerCategory) -> usize {
    const WINDOW_SIZE_DEFAULT: usize = 1;
    match var_os(format!("SERVO_HEARTBEAT_WINDOW_{:?}", category)) {
        Some(w) => match w.into_string() {
            Ok(s) => s.parse::<usize>().unwrap_or(WINDOW_SIZE_DEFAULT),
            _ => WINDOW_SIZE_DEFAULT,
        },
        None => WINDOW_SIZE_DEFAULT,
    }
}

/// Possibly create a heartbeat
fn maybe_create_heartbeat(hbs: &mut HashMap<ProfilerCategory, Heartbeat>,
                          category: ProfilerCategory) {
    if is_create_heartbeat(&category) {
        // get optional log file
        let logfile: Option<File> = get_heartbeat_log(&category);
        // window size
        let window_size: usize = get_heartbeat_window_size(&category);
        // create the heartbeat
        match Heartbeat::new(window_size, Some(heartbeat_window_callback), logfile) {
            Ok(hb) => {
                debug!("Created heartbeat for {:?}", category);
                hbs.insert(category, hb);
            },
            Err(e) => warn!("Failed to create heartbeat for {:?}: {}", category, e),
        }
    };
}

/// Log heartbeat records up to the buffer index
fn log_heartbeat_records(hb: &mut Heartbeat) {
    match hb.log_to_buffer_index() {
        Ok(_) => (),
        Err(e) => warn!("Failed to write heartbeat log: {}", Error::description(&e)),
    }
}

/// Callback function used to log the window buffer.
/// When this is called from native C, the heartbeat is safely locked
extern fn heartbeat_window_callback(hb: *const HeartbeatContext) {
    unsafe {
        if let Some(hbs_ptr) = HBS {
            for (_, v) in (*hbs_ptr).iter_mut() {
                if &v.hb as *const HeartbeatContext == hb {
                    log_heartbeat_records(v);
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use crate::{CompileError, Config, Syntax};

use std::path::{Path, PathBuf};
use std::str::FromStr;

use mime::Mime;
use quote::ToTokens;

pub struct TemplateInput<'a> {
    pub ast: &'a syn::DeriveInput,
    pub config: &'a Config<'a>,
    pub syntax: &'a Syntax<'a>,
    pub source: Source,
    pub print: Print,
    pub escaper: &'a str,
    pub ext: Option<String>,
    pub mime_type: String,
    pub parent: Option<&'a syn::Type>,
    pub path: PathBuf,
}

impl TemplateInput<'_> {
    /// Extract the template metadata from the `DeriveInput` structure. This
    /// mostly recovers the data for the `TemplateInput` fields from the
    /// `template()` attribute list fields; it also finds the of the `_parent`
    /// field, if any.
    pub fn new<'n>(
        ast: &'n syn::DeriveInput,
        config: &'n Config<'_>,
    ) -> Result<TemplateInput<'n>, CompileError> {
        // Check that an attribute called `template()` exists once and that it is
        // the proper type (list).
        let mut template_args = None;
        for attr in &ast.attrs {
            if attr.path.is_ident("template") {
                if template_args.is_some() {
                    return Err(CompileError::Static("duplicated 'template' attribute"));
                }
                let template = attr.parse_meta().map_err(|e| {
                    CompileError::String(format!("unable to parse attribute: {}", e))
                })?;
                match template {
                    syn::Meta::List(inner) => template_args = Some(inner),
                    _ => {
                        return Err(CompileError::Static(
                            "attribute 'template' has incorrect type",
                        ));
                    }
                }
            }
        }
        let template_args =
            template_args.ok_or(CompileError::Static("no attribute 'template' found"))?;

        // Loop over the meta attributes and find everything that we
        // understand. Raise panics if something is not right.
        // `source` contains an enum that can represent `path` or `source`.
        let mut source = None;
        let mut print = Print::None;
        let mut escaping = None;
        let mut ext = None;
        let mut syntax = None;
        for item in template_args.nested {
            let pair = match item {
                syn::NestedMeta::Meta(syn::Meta::NameValue(ref pair)) => pair,
                _ => {
                    return Err(format!(
                        "unsupported attribute argument {:?}",
                        item.to_token_stream()
                    )
                    .into())
                }
            };

            if pair.path.is_ident("path") {
                if let syn::Lit::Str(ref s) = pair.lit {
                    if source.is_some() {
                        return Err("must specify 'source' or 'path', not both".into());
                    }
                    source = Some(Source::Path(s.value()));
                } else {
                    return Err("template path must be string literal".into());
                }
            } else if pair.path.is_ident("source") {
                if let syn::Lit::Str(ref s) = pair.lit {
                    if source.is_some() {
                        return Err("must specify 'source' or 'path', not both".into());
                    }
                    source = Some(Source::Source(s.value()));
                } else {
                    return Err("template source must be string literal".into());
                }
            } else if pair.path.is_ident("print") {
                if let syn::Lit::Str(ref s) = pair.lit {
                    print = s.value().parse()?;
                } else {
                    return Err("print value must be string literal".into());
                }
            } else if pair.path.is_ident("escape") {
                if let syn::Lit::Str(ref s) = pair.lit {
                    escaping = Some(s.value());
                } else {
                    return Err("escape value must be string literal".into());
                }
            } else if pair.path.is_ident("ext") {
                if let syn::Lit::Str(ref s) = pair.lit {
                    ext = Some(s.value());
                } else {
                    return Err("ext value must be string literal".into());
                }
            } else if pair.path.is_ident("syntax") {
                if let syn::Lit::Str(ref s) = pair.lit {
                    syntax = Some(s.value())
                } else {
                    return Err("syntax value must be string literal".into());
                }
            } else {
                return Err(format!(
                    "unsupported attribute key '{}' found",
                    pair.path.to_token_stream()
                )
                .into());
            }
        }

        // Validate the `source` and `ext` value together, since they are
        // related. In case `source` was used instead of `path`, the value
        // of `ext` is merged into a synthetic `path` value here.
        let source = source.expect("template path or source not found in attributes");
        let path = match (&source, &ext) {
            (&Source::Path(ref path), _) => config.find_template(path, None)?,
            (&Source::Source(_), Some(ext)) => PathBuf::from(format!("{}.{}", ast.ident, ext)),
            (&Source::Source(_), None) => {
                return Err("must include 'ext' attribute when using 'source' attribute".into())
            }
        };

        // Check to see if a `_parent` field was defined on the context
        // struct, and store the type for it for use in the code generator.
        let parent = match ast.data {
            syn::Data::Struct(syn::DataStruct {
                fields: syn::Fields::Named(ref fields),
                ..
            }) => fields
                .named
                .iter()
                .find(|f| f.ident.as_ref().filter(|name| *name == "_parent").is_some())
                .map(|f| &f.ty),
            _ => None,
        };

        if parent.is_some() {
            eprint!(
                "   --> in struct {}\n   = use of deprecated field '_parent'\n",
                ast.ident
            );
        }

        // Validate syntax
        let syntax = syntax.map_or_else(
            || Ok(config.syntaxes.get(config.default_syntax).unwrap()),
            |s| {
                config.syntaxes.get(&s).ok_or_else(|| {
                    CompileError::String(format!("attribute syntax {} not exist", s))
                })
            },
        )?;

        // Match extension against defined output formats

        let escaping = escaping.unwrap_or_else(|| {
            path.extension()
                .map(|s| s.to_str().unwrap())
                .unwrap_or("")
                .to_string()
        });

        let mut escaper = None;
        for (extensions, path) in &config.escapers {
            if extensions.contains(&escaping) {
                escaper = Some(path);
                break;
            }
        }

        let escaper = escaper.ok_or_else(|| {
            CompileError::String(format!("no escaper defined for extension '{}'", escaping,))
        })?;

        let mime_type =
            extension_to_mime_type(ext_default_to_path(ext.as_deref(), &path).unwrap_or("txt"))
                .to_string();

        Ok(TemplateInput {
            ast,
            config,
            syntax,
            source,
            print,
            escaper,
            ext,
            mime_type,
            parent,
            path,
        })
    }

    #[inline]
    pub fn extension(&self) -> Option<&str> {
        ext_default_to_path(self.ext.as_deref(), &self.path)
    }
}

#[inline]
pub fn ext_default_to_path<'a>(ext: Option<&'a str>, path: &'a Path) -> Option<&'a str> {
    ext.or_else(|| extension(path))
}

fn extension(path: &Path) -> Option<&str> {
    let ext = path.extension().map(|s| s.to_str().unwrap())?;

    const JINJA_EXTENSIONS: [&str; 3] = ["j2", "jinja", "jinja2"];
    if JINJA_EXTENSIONS.contains(&ext) {
        Path::new(path.file_stem().unwrap())
            .extension()
            .map(|s| s.to_str().unwrap())
            .or(Some(ext))
    } else {
        Some(ext)
    }
}

pub enum Source {
    Path(String),
    Source(String),
}

#[derive(PartialEq)]
pub enum Print {
    All,
    Ast,
    Code,
    None,
}

impl FromStr for Print {
    type Err = CompileError;

    fn from_str(s: &str) -> Result<Print, Self::Err> {
        use self::Print::*;
        Ok(match s {
            "all" => All,
            "ast" => Ast,
            "code" => Code,
            "none" => None,
            v => return Err(format!("invalid value for print option: {}", v,).into()),
        })
    }
}

#[doc(hidden)]
pub fn extension_to_mime_type(ext: &str) -> Mime {
    let basic_type = mime_guess::from_ext(ext).first_or_octet_stream();
    for (simple, utf_8) in &TEXT_TYPES {
        if &basic_type == simple {
            return utf_8.clone();
        }
    }
    basic_type
}

const TEXT_TYPES: [(Mime, Mime); 6] = [
    (mime::TEXT_PLAIN, mime::TEXT_PLAIN_UTF_8),
    (mime::TEXT_HTML, mime::TEXT_HTML_UTF_8),
    (mime::TEXT_CSS, mime::TEXT_CSS_UTF_8),
    (mime::TEXT_CSV, mime::TEXT_CSV_UTF_8),
    (
        mime::TEXT_TAB_SEPARATED_VALUES,
        mime::TEXT_TAB_SEPARATED_VALUES_UTF_8,
    ),
    (
        mime::APPLICATION_JAVASCRIPT,
        mime::APPLICATION_JAVASCRIPT_UTF_8,
    ),
];

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_ext() {
        assert_eq!(extension(Path::new("foo-bar.txt")), Some("txt"));
        assert_eq!(extension(Path::new("foo-bar.html")), Some("html"));
        assert_eq!(extension(Path::new("foo-bar.unknown")), Some("unknown"));

        assert_eq!(extension(Path::new("foo/bar/baz.txt")), Some("txt"));
        assert_eq!(extension(Path::new("foo/bar/baz.html")), Some("html"));
        assert_eq!(extension(Path::new("foo/bar/baz.unknown")), Some("unknown"));
    }

    #[test]
    fn test_double_ext() {
        assert_eq!(extension(Path::new("foo-bar.html.txt")), Some("txt"));
        assert_eq!(extension(Path::new("foo-bar.txt.html")), Some("html"));
        assert_eq!(extension(Path::new("foo-bar.txt.unknown")), Some("unknown"));

        assert_eq!(extension(Path::new("foo/bar/baz.html.txt")), Some("txt"));
        assert_eq!(extension(Path::new("foo/bar/baz.txt.html")), Some("html"));
        assert_eq!(
            extension(Path::new("foo/bar/baz.txt.unknown")),
            Some("unknown")
        );
    }

    #[test]
    fn test_skip_jinja_ext() {
        assert_eq!(extension(Path::new("foo-bar.html.j2")), Some("html"));
        assert_eq!(extension(Path::new("foo-bar.html.jinja")), Some("html"));
        assert_eq!(extension(Path::new("foo-bar.html.jinja2")), Some("html"));

        assert_eq!(extension(Path::new("foo/bar/baz.txt.j2")), Some("txt"));
        assert_eq!(extension(Path::new("foo/bar/baz.txt.jinja")), Some("txt"));
        assert_eq!(extension(Path::new("foo/bar/baz.txt.jinja2")), Some("txt"));
    }

    #[test]
    fn test_only_jinja_ext() {
        assert_eq!(extension(Path::new("foo-bar.j2")), Some("j2"));
        assert_eq!(extension(Path::new("foo-bar.jinja")), Some("jinja"));
        assert_eq!(extension(Path::new("foo-bar.jinja2")), Some("jinja2"));
    }
}
<commit_msg>Tweak attribute parsing some more<commit_after>use crate::{CompileError, Config, Syntax};

use std::path::{Path, PathBuf};
use std::str::FromStr;

use mime::Mime;
use quote::ToTokens;

pub struct TemplateInput<'a> {
    pub ast: &'a syn::DeriveInput,
    pub config: &'a Config<'a>,
    pub syntax: &'a Syntax<'a>,
    pub source: Source,
    pub print: Print,
    pub escaper: &'a str,
    pub ext: Option<String>,
    pub mime_type: String,
    pub parent: Option<&'a syn::Type>,
    pub path: PathBuf,
}

impl TemplateInput<'_> {
    /// Extract the template metadata from the `DeriveInput` structure. This
    /// mostly recovers the data for the `TemplateInput` fields from the
    /// `template()` attribute list fields; it also finds the of the `_parent`
    /// field, if any.
    pub fn new<'n>(
        ast: &'n syn::DeriveInput,
        config: &'n Config<'_>,
    ) -> Result<TemplateInput<'n>, CompileError> {
        // Check that an attribute called `template()` exists once and that it is
        // the proper type (list).
        let mut template_args = None;
        for attr in &ast.attrs {
            if attr.path.is_ident("template") {
                if template_args.is_some() {
                    return Err(CompileError::Static("duplicated 'template' attribute"));
                }

                match attr.parse_meta() {
                    Ok(syn::Meta::List(syn::MetaList { nested, .. })) => {
                        template_args = Some(nested);
                    }
                    Ok(_) => return Err("'template' attribute must be a list".into()),
                    Err(e) => return Err(format!("unable to parse attribute: {}", e).into()),
                }
            }
        }
        let template_args =
            template_args.ok_or(CompileError::Static("no attribute 'template' found"))?;

        // Loop over the meta attributes and find everything that we
        // understand. Raise panics if something is not right.
        // `source` contains an enum that can represent `path` or `source`.
        let mut source = None;
        let mut print = Print::None;
        let mut escaping = None;
        let mut ext = None;
        let mut syntax = None;
        for item in template_args {
            let pair = match item {
                syn::NestedMeta::Meta(syn::Meta::NameValue(ref pair)) => pair,
                _ => {
                    return Err(format!(
                        "unsupported attribute argument {:?}",
                        item.to_token_stream()
                    )
                    .into())
                }
            };

            if pair.path.is_ident("path") {
                if let syn::Lit::Str(ref s) = pair.lit {
                    if source.is_some() {
                        return Err("must specify 'source' or 'path', not both".into());
                    }
                    source = Some(Source::Path(s.value()));
                } else {
                    return Err("template path must be string literal".into());
                }
            } else if pair.path.is_ident("source") {
                if let syn::Lit::Str(ref s) = pair.lit {
                    if source.is_some() {
                        return Err("must specify 'source' or 'path', not both".into());
                    }
                    source = Some(Source::Source(s.value()));
                } else {
                    return Err("template source must be string literal".into());
                }
            } else if pair.path.is_ident("print") {
                if let syn::Lit::Str(ref s) = pair.lit {
                    print = s.value().parse()?;
                } else {
                    return Err("print value must be string literal".into());
                }
            } else if pair.path.is_ident("escape") {
                if let syn::Lit::Str(ref s) = pair.lit {
                    escaping = Some(s.value());
                } else {
                    return Err("escape value must be string literal".into());
                }
            } else if pair.path.is_ident("ext") {
                if let syn::Lit::Str(ref s) = pair.lit {
                    ext = Some(s.value());
                } else {
                    return Err("ext value must be string literal".into());
                }
            } else if pair.path.is_ident("syntax") {
                if let syn::Lit::Str(ref s) = pair.lit {
                    syntax = Some(s.value())
                } else {
                    return Err("syntax value must be string literal".into());
                }
            } else {
                return Err(format!(
                    "unsupported attribute key '{}' found",
                    pair.path.to_token_stream()
                )
                .into());
            }
        }

        // Validate the `source` and `ext` value together, since they are
        // related. In case `source` was used instead of `path`, the value
        // of `ext` is merged into a synthetic `path` value here.
        let source = source.expect("template path or source not found in attributes");
        let path = match (&source, &ext) {
            (&Source::Path(ref path), _) => config.find_template(path, None)?,
            (&Source::Source(_), Some(ext)) => PathBuf::from(format!("{}.{}", ast.ident, ext)),
            (&Source::Source(_), None) => {
                return Err("must include 'ext' attribute when using 'source' attribute".into())
            }
        };

        // Check to see if a `_parent` field was defined on the context
        // struct, and store the type for it for use in the code generator.
        let parent = match ast.data {
            syn::Data::Struct(syn::DataStruct {
                fields: syn::Fields::Named(ref fields),
                ..
            }) => fields
                .named
                .iter()
                .find(|f| f.ident.as_ref().filter(|name| *name == "_parent").is_some())
                .map(|f| &f.ty),
            _ => None,
        };

        if parent.is_some() {
            eprint!(
                "   --> in struct {}\n   = use of deprecated field '_parent'\n",
                ast.ident
            );
        }

        // Validate syntax
        let syntax = syntax.map_or_else(
            || Ok(config.syntaxes.get(config.default_syntax).unwrap()),
            |s| {
                config.syntaxes.get(&s).ok_or_else(|| {
                    CompileError::String(format!("attribute syntax {} not exist", s))
                })
            },
        )?;

        // Match extension against defined output formats

        let escaping = escaping.unwrap_or_else(|| {
            path.extension()
                .map(|s| s.to_str().unwrap())
                .unwrap_or("")
                .to_string()
        });

        let mut escaper = None;
        for (extensions, path) in &config.escapers {
            if extensions.contains(&escaping) {
                escaper = Some(path);
                break;
            }
        }

        let escaper = escaper.ok_or_else(|| {
            CompileError::String(format!("no escaper defined for extension '{}'", escaping,))
        })?;

        let mime_type =
            extension_to_mime_type(ext_default_to_path(ext.as_deref(), &path).unwrap_or("txt"))
                .to_string();

        Ok(TemplateInput {
            ast,
            config,
            syntax,
            source,
            print,
            escaper,
            ext,
            mime_type,
            parent,
            path,
        })
    }

    #[inline]
    pub fn extension(&self) -> Option<&str> {
        ext_default_to_path(self.ext.as_deref(), &self.path)
    }
}

#[inline]
pub fn ext_default_to_path<'a>(ext: Option<&'a str>, path: &'a Path) -> Option<&'a str> {
    ext.or_else(|| extension(path))
}

fn extension(path: &Path) -> Option<&str> {
    let ext = path.extension().map(|s| s.to_str().unwrap())?;

    const JINJA_EXTENSIONS: [&str; 3] = ["j2", "jinja", "jinja2"];
    if JINJA_EXTENSIONS.contains(&ext) {
        Path::new(path.file_stem().unwrap())
            .extension()
            .map(|s| s.to_str().unwrap())
            .or(Some(ext))
    } else {
        Some(ext)
    }
}

pub enum Source {
    Path(String),
    Source(String),
}

#[derive(PartialEq)]
pub enum Print {
    All,
    Ast,
    Code,
    None,
}

impl FromStr for Print {
    type Err = CompileError;

    fn from_str(s: &str) -> Result<Print, Self::Err> {
        use self::Print::*;
        Ok(match s {
            "all" => All,
            "ast" => Ast,
            "code" => Code,
            "none" => None,
            v => return Err(format!("invalid value for print option: {}", v,).into()),
        })
    }
}

#[doc(hidden)]
pub fn extension_to_mime_type(ext: &str) -> Mime {
    let basic_type = mime_guess::from_ext(ext).first_or_octet_stream();
    for (simple, utf_8) in &TEXT_TYPES {
        if &basic_type == simple {
            return utf_8.clone();
        }
    }
    basic_type
}

const TEXT_TYPES: [(Mime, Mime); 6] = [
    (mime::TEXT_PLAIN, mime::TEXT_PLAIN_UTF_8),
    (mime::TEXT_HTML, mime::TEXT_HTML_UTF_8),
    (mime::TEXT_CSS, mime::TEXT_CSS_UTF_8),
    (mime::TEXT_CSV, mime::TEXT_CSV_UTF_8),
    (
        mime::TEXT_TAB_SEPARATED_VALUES,
        mime::TEXT_TAB_SEPARATED_VALUES_UTF_8,
    ),
    (
        mime::APPLICATION_JAVASCRIPT,
        mime::APPLICATION_JAVASCRIPT_UTF_8,
    ),
];

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_ext() {
        assert_eq!(extension(Path::new("foo-bar.txt")), Some("txt"));
        assert_eq!(extension(Path::new("foo-bar.html")), Some("html"));
        assert_eq!(extension(Path::new("foo-bar.unknown")), Some("unknown"));

        assert_eq!(extension(Path::new("foo/bar/baz.txt")), Some("txt"));
        assert_eq!(extension(Path::new("foo/bar/baz.html")), Some("html"));
        assert_eq!(extension(Path::new("foo/bar/baz.unknown")), Some("unknown"));
    }

    #[test]
    fn test_double_ext() {
        assert_eq!(extension(Path::new("foo-bar.html.txt")), Some("txt"));
        assert_eq!(extension(Path::new("foo-bar.txt.html")), Some("html"));
        assert_eq!(extension(Path::new("foo-bar.txt.unknown")), Some("unknown"));

        assert_eq!(extension(Path::new("foo/bar/baz.html.txt")), Some("txt"));
        assert_eq!(extension(Path::new("foo/bar/baz.txt.html")), Some("html"));
        assert_eq!(
            extension(Path::new("foo/bar/baz.txt.unknown")),
            Some("unknown")
        );
    }

    #[test]
    fn test_skip_jinja_ext() {
        assert_eq!(extension(Path::new("foo-bar.html.j2")), Some("html"));
        assert_eq!(extension(Path::new("foo-bar.html.jinja")), Some("html"));
        assert_eq!(extension(Path::new("foo-bar.html.jinja2")), Some("html"));

        assert_eq!(extension(Path::new("foo/bar/baz.txt.j2")), Some("txt"));
        assert_eq!(extension(Path::new("foo/bar/baz.txt.jinja")), Some("txt"));
        assert_eq!(extension(Path::new("foo/bar/baz.txt.jinja2")), Some("txt"));
    }

    #[test]
    fn test_only_jinja_ext() {
        assert_eq!(extension(Path::new("foo-bar.j2")), Some("j2"));
        assert_eq!(extension(Path::new("foo-bar.jinja")), Some("jinja"));
        assert_eq!(extension(Path::new("foo-bar.jinja2")), Some("jinja2"));
    }
}
<|endoftext|>


<commit_before>extern crate iron;
extern crate rustc_serialize;

use iron::prelude::*;
use iron::status;
use diesel::prelude::*;
use rustc_serialize::json;
use database;

pub fn index(request: &mut Request) -> IronResult<Response> {
    println!("Started GET \"/api\" for {}", request.remote_addr);

    Ok(Response::with((status::Ok, "Welcome to Lugh API!")))
}

pub fn translations(request: &mut Request) -> IronResult<Response> {
    use schema::translations::dsl::*;
    use models::*;

    println!("Started GET \"/api/translations\" for {}", request.remote_addr);

    let connection = database::establish_connection();
    let results = translations.load::<Translation>(&connection)
        .expect("Error loading translations");

    println!("Returns {} translations", results.len());

    let payload = json::encode(&results).unwrap();

    Ok(Response::with((status::Ok, payload)))
}
<commit_msg>Set Content-Type header to application/json<commit_after>extern crate iron;
extern crate rustc_serialize;

use iron::headers::ContentType;
use iron::prelude::*;
use iron::status;
use diesel::prelude::*;
use rustc_serialize::json;
use database;

pub fn index(request: &mut Request) -> IronResult<Response> {
    println!("Started GET \"/api\" for {}", request.remote_addr);

    Ok(Response::with((status::Ok, "Welcome to Lugh API!")))
}

pub fn translations(request: &mut Request) -> IronResult<Response> {
    use schema::translations::dsl::*;
    use models::*;

    println!("Started GET \"/api/translations\" for {}", request.remote_addr);

    let connection = database::establish_connection();
    let results = translations.load::<Translation>(&connection)
        .expect("Error loading translations");

    println!("Returns {} translations", results.len());

    let payload = json::encode(&results).unwrap();

    Ok(Response::with((ContentType::json().0, status::Ok, payload)))
}
<|endoftext|>