<commit_before>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{
    backend::k8s::node::K8sNode, create_k8s_client, query_sequence_numbers, remove_helm_release,
    set_eks_nodegroup_size, set_validator_image_tag, uninstall_from_k8s_cluster, ChainInfo,
    FullNode, Node, Result, Swarm, Validator, Version,
};
use anyhow::{anyhow, bail, format_err};
use diem_config::config::NodeConfig;
use diem_logger::*;
use diem_sdk::{
    crypto::ed25519::Ed25519PrivateKey,
    types::{
        chain_id::{ChainId, NamedChain},
        AccountKey, LocalAccount, PeerId,
    },
};
use k8s_openapi::api::core::v1::Service;
use kube::{
    api::{Api, ListParams},
    client::Client as K8sClient,
};
use std::{collections::HashMap, convert::TryFrom, env, process::Command, str, sync::Arc};
use tokio::{runtime::Runtime, time::Duration};

const JSON_RPC_PORT: u32 = 80;
const VALIDATOR_LB: &str = "validator-fullnode-lb";

pub struct K8sSwarm {
    validators: HashMap<PeerId, K8sNode>,
    fullnodes: HashMap<PeerId, K8sNode>,
    root_account: LocalAccount,
    treasury_compliance_account: LocalAccount,
    designated_dealer_account: LocalAccount,
    kube_client: K8sClient,
    cluster_name: String,
    helm_repo: String,
    versions: Arc<HashMap<Version, String>>,
    pub chain_id: ChainId,
}

impl K8sSwarm {
    pub async fn new(
        root_key: &[u8],
        treasury_compliance_key: &[u8],
        cluster_name: &str,
        helm_repo: &str,
        image_tag: &str,
        base_image_tag: &str,
    ) -> Result<Self> {
        let kube_client = create_k8s_client().await;
        let fullnodes = HashMap::new();
        let validators = get_validators(kube_client.clone(), image_tag).await?;

        let client = validators.values().next().unwrap().json_rpc_client();
        let key = load_root_key(root_key);
        let account_key = AccountKey::from_private_key(key);
        let address = diem_sdk::types::account_config::diem_root_address();
        let sequence_number = query_sequence_numbers(&client, &[address])
            .await
            .map_err(|e| {
                format_err!(
                    "query_sequence_numbers on {:?} for dd account failed: {}",
                    client,
                    e
                )
            })?[0];
        let root_account = LocalAccount::new(address, account_key, sequence_number);

        let key = load_tc_key(treasury_compliance_key);
        let account_key = AccountKey::from_private_key(key);
        let address = diem_sdk::types::account_config::treasury_compliance_account_address();
        let sequence_number = query_sequence_numbers(&client, &[address])
            .await
            .map_err(|e| {
                format_err!(
                    "query_sequence_numbers on {:?} for dd account failed: {}",
                    client,
                    e
                )
            })?[0];
        let treasury_compliance_account = LocalAccount::new(address, account_key, sequence_number);

        let key = load_tc_key(treasury_compliance_key);
        let account_key = AccountKey::from_private_key(key);
        let address = diem_sdk::types::account_config::testnet_dd_account_address();
        let sequence_number = query_sequence_numbers(&client, &[address])
            .await
            .map_err(|e| {
                format_err!(
                    "query_sequence_numbers on {:?} for dd account failed: {}",
                    client,
                    e
                )
            })?[0];
        let designated_dealer_account = LocalAccount::new(address, account_key, sequence_number);

        let mut versions = HashMap::new();
        let base_version = Version::new(0, base_image_tag.to_string());
        let cur_version = Version::new(1, image_tag.to_string());
        versions.insert(cur_version, image_tag.to_string());
        versions.insert(base_version, base_image_tag.to_string());

        Ok(Self {
            validators,
            fullnodes,
            root_account,
            treasury_compliance_account,
            designated_dealer_account,
            kube_client,
            chain_id: ChainId::new(NamedChain::DEVNET.id()),
            cluster_name: cluster_name.to_string(),
            helm_repo: helm_repo.to_string(),
            versions: Arc::new(versions),
        })
    }

    fn get_url(&self) -> String {
        self.validators
            .values()
            .next()
            .unwrap()
            .json_rpc_endpoint()
            .to_string()
    }

    #[allow(dead_code)]
    fn get_kube_client(&self) -> K8sClient {
        self.kube_client.clone()
    }
}

impl Drop for K8sSwarm {
    // When the K8sSwarm struct goes out of scope we need to wipe the chain state and scale down
    fn drop(&mut self) {
        uninstall_from_k8s_cluster().unwrap();
        set_eks_nodegroup_size(self.cluster_name.clone(), 0, true).unwrap();
    }
}

impl Swarm for K8sSwarm {
    fn health_check(&mut self) -> Result<()> {
        nodes_healthcheck(Box::new(
            self.validators
                .values_mut()
                .map(|v| v as &mut dyn Validator),
        ))
    }

    fn validators<'a>(&'a self) -> Box<dyn Iterator<Item = &'a dyn Validator> + 'a> {
        Box::new(self.validators.values().map(|v| v as &'a dyn Validator))
    }

    fn validators_mut<'a>(&'a mut self) -> Box<dyn Iterator<Item = &'a mut dyn Validator> + 'a> {
        Box::new(
            self.validators
                .values_mut()
                .map(|v| v as &'a mut dyn Validator),
        )
    }

    fn validator(&self, id: PeerId) -> Option<&dyn Validator> {
        self.validators.get(&id).map(|v| v as &dyn Validator)
    }

    fn validator_mut(&mut self, id: PeerId) -> Option<&mut dyn Validator> {
        self.validators
            .get_mut(&id)
            .map(|v| v as &mut dyn Validator)
    }

    fn upgrade_validator(&mut self, id: PeerId, version: &Version) -> Result<()> {
        let validator = self
            .validators
            .get_mut(&id)
            .ok_or_else(|| anyhow!("Invalid id: {}", id))?;
        let version = self
            .versions
            .get(version)
            .cloned()
            .ok_or_else(|| anyhow!("Invalid version: {:?}", version))?;
        set_validator_image_tag(validator.name(), &version, &self.helm_repo)
    }

    fn full_nodes<'a>(&'a self) -> Box<dyn Iterator<Item = &'a dyn FullNode> + 'a> {
        Box::new(self.fullnodes.values().map(|v| v as &'a dyn FullNode))
    }

    fn full_nodes_mut<'a>(&'a mut self) -> Box<dyn Iterator<Item = &'a mut dyn FullNode> + 'a> {
        Box::new(
            self.fullnodes
                .values_mut()
                .map(|v| v as &'a mut dyn FullNode),
        )
    }

    fn full_node(&self, id: PeerId) -> Option<&dyn FullNode> {
        self.fullnodes.get(&id).map(|v| v as &dyn FullNode)
    }

    fn full_node_mut(&mut self, id: PeerId) -> Option<&mut dyn FullNode> {
        self.fullnodes.get_mut(&id).map(|v| v as &mut dyn FullNode)
    }

    fn add_validator(&mut self, _version: &Version, _template: NodeConfig) -> Result<PeerId> {
        todo!()
    }

    fn remove_validator(&mut self, id: PeerId) -> Result<()> {
        remove_helm_release(self.validator(id).unwrap().name())
    }

    fn add_full_node(&mut self, _version: &Version, _template: NodeConfig) -> Result<PeerId> {
        todo!()
    }

    fn remove_full_node(&mut self, _id: PeerId) -> Result<()> {
        todo!()
    }

    fn versions<'a>(&'a self) -> Box<dyn Iterator<Item = Version> + 'a> {
        Box::new(self.versions.keys().cloned())
    }

    fn chain_info(&mut self) -> ChainInfo<'_> {
        let url = self.get_url();
        ChainInfo::new(
            &mut self.root_account,
            &mut self.treasury_compliance_account,
            &mut self.designated_dealer_account,
            url,
            self.chain_id,
        )
    }

    // Returns env CENTRAL_LOGGING_ADDRESS if present (without timestamps)
    // otherwise returns a kubectl logs command to retrieve the logs manually
    fn logs_location(&mut self) -> String {
        if let Ok(central_logging_address) = std::env::var("CENTRAL_LOGGING_ADDRESS") {
            central_logging_address
        } else {
            let hostname_output = Command::new("hostname")
                .output()
                .expect("failed to get pod hostname");
            let hostname = String::from_utf8(hostname_output.stdout).unwrap();
            format!(
                "aws eks --region us-west-2 update-kubeconfig --name {} && kubectl logs {}",
                &self.cluster_name, hostname
            )
        }
    }
}

pub(crate) fn k8s_retry_strategy() -> impl Iterator<Item = Duration> {
    diem_retrier::exp_retry_strategy(1000, 5000, 30)
}

#[derive(Clone, Debug)]
pub struct KubeService {
    pub name: String,
    pub host_ip: String,
}

impl TryFrom<Service> for KubeService {
    type Error = anyhow::Error;

    fn try_from(service: Service) -> Result<Self, Self::Error> {
        let metadata = service.metadata;
        let name = metadata
            .name
            .ok_or_else(|| format_err!("node name not found"))?;
        let spec = service
            .spec
            .ok_or_else(|| format_err!("spec not found for node"))?;
        let host_ip = spec.cluster_ip.unwrap_or_default();
        Ok(Self { name, host_ip })
    }
}

async fn list_services(client: K8sClient) -> Result<Vec<KubeService>> {
    let node_api: Api<Service> = Api::all(client);
    let lp = ListParams::default();
    let services = node_api.list(&lp).await?.items;
    services.into_iter().map(KubeService::try_from).collect()
}

pub(crate) async fn get_validators(
    client: K8sClient,
    image_tag: &str,
) -> Result<HashMap<PeerId, K8sNode>> {
    let services = list_services(client).await?;
    services
        .into_iter()
        .filter(|s| s.name.contains(VALIDATOR_LB))
        .map(|s| {
            let node_id = parse_node_id(&s.name).expect("error to parse node id");
            let node = K8sNode {
                name: format!("val{}", node_id),
                // TODO: fetch this from running node
                peer_id: PeerId::random(),
                node_id,
                ip: s.host_ip.clone(),
                port: JSON_RPC_PORT,
                dns: s.name,
                version: Version::new(0, image_tag.to_string()),
                runtime: Runtime::new().unwrap(),
            };
            Ok((node.peer_id(), node))
        })
        .collect::<Result<HashMap<_, _>>>()
}

fn parse_node_id(s: &str) -> Result<usize> {
    let v = s.split('-').collect::<Vec<&str>>();
    if v.len() < 5 {
        return Err(format_err!("Failed to parse {:?} node id format", s));
    }
    let idx: usize = v[0][3..].parse().unwrap();
    Ok(idx)
}

fn load_root_key(root_key_bytes: &[u8]) -> Ed25519PrivateKey {
    Ed25519PrivateKey::try_from(root_key_bytes).unwrap()
}

fn load_tc_key(tc_key_bytes: &[u8]) -> Ed25519PrivateKey {
    Ed25519PrivateKey::try_from(tc_key_bytes).unwrap()
}

pub fn nodes_healthcheck<'a>(
    nodes: Box<dyn Iterator<Item = &'a mut dyn Validator> + 'a>,
) -> Result<()> {
    let unhealthy_nodes = nodes
        .filter_map(|node| {
            let node_name = node.name().to_string();
            println!("Attempting health check: {}", node_name);
            // perform healthcheck with retry, returning unhealthy
            let check = diem_retrier::retry(k8s_retry_strategy(), || match node.health_check() {
                Ok(_) => {
                    println!("Node {} healthy", node_name);
                    Ok(())
                }
                Err(ref x) => {
                    debug!("Node {} unhealthy: {}", node_name, x);
                    Err(())
                }
            });
            if check.is_err() {
                return Some(node_name);
            }
            None
        })
        .collect::<Vec<_>>();
    if !unhealthy_nodes.is_empty() {
        bail!("Unhealthy validators after cleanup: {:?}", unhealthy_nodes);
    }
    println!("All validators healthy after cleanup!");
    Ok(())
}
<commit_msg>[forge] extend waiting time for node recovery to catch up peers<commit_after>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{
    backend::k8s::node::K8sNode, create_k8s_client, query_sequence_numbers, remove_helm_release,
    set_eks_nodegroup_size, set_validator_image_tag, uninstall_from_k8s_cluster, ChainInfo,
    FullNode, Node, Result, Swarm, Validator, Version,
};
use anyhow::{anyhow, bail, format_err};
use diem_config::config::NodeConfig;
use diem_logger::*;
use diem_sdk::{
    crypto::ed25519::Ed25519PrivateKey,
    types::{
        chain_id::{ChainId, NamedChain},
        AccountKey, LocalAccount, PeerId,
    },
};
use k8s_openapi::api::core::v1::Service;
use kube::{
    api::{Api, ListParams},
    client::Client as K8sClient,
};
use std::{collections::HashMap, convert::TryFrom, env, process::Command, str, sync::Arc, thread};
use tokio::{runtime::Runtime, time::Duration};

const JSON_RPC_PORT: u32 = 80;
const VALIDATOR_LB: &str = "validator-fullnode-lb";

pub struct K8sSwarm {
    validators: HashMap<PeerId, K8sNode>,
    fullnodes: HashMap<PeerId, K8sNode>,
    root_account: LocalAccount,
    treasury_compliance_account: LocalAccount,
    designated_dealer_account: LocalAccount,
    kube_client: K8sClient,
    cluster_name: String,
    helm_repo: String,
    versions: Arc<HashMap<Version, String>>,
    pub chain_id: ChainId,
}

impl K8sSwarm {
    pub async fn new(
        root_key: &[u8],
        treasury_compliance_key: &[u8],
        cluster_name: &str,
        helm_repo: &str,
        image_tag: &str,
        base_image_tag: &str,
    ) -> Result<Self> {
        let kube_client = create_k8s_client().await;
        let fullnodes = HashMap::new();
        let validators = get_validators(kube_client.clone(), image_tag).await?;

        let client = validators.values().next().unwrap().json_rpc_client();
        let key = load_root_key(root_key);
        let account_key = AccountKey::from_private_key(key);
        let address = diem_sdk::types::account_config::diem_root_address();
        let sequence_number = query_sequence_numbers(&client, &[address])
            .await
            .map_err(|e| {
                format_err!(
                    "query_sequence_numbers on {:?} for dd account failed: {}",
                    client,
                    e
                )
            })?[0];
        let root_account = LocalAccount::new(address, account_key, sequence_number);

        let key = load_tc_key(treasury_compliance_key);
        let account_key = AccountKey::from_private_key(key);
        let address = diem_sdk::types::account_config::treasury_compliance_account_address();
        let sequence_number = query_sequence_numbers(&client, &[address])
            .await
            .map_err(|e| {
                format_err!(
                    "query_sequence_numbers on {:?} for dd account failed: {}",
                    client,
                    e
                )
            })?[0];
        let treasury_compliance_account = LocalAccount::new(address, account_key, sequence_number);

        let key = load_tc_key(treasury_compliance_key);
        let account_key = AccountKey::from_private_key(key);
        let address = diem_sdk::types::account_config::testnet_dd_account_address();
        let sequence_number = query_sequence_numbers(&client, &[address])
            .await
            .map_err(|e| {
                format_err!(
                    "query_sequence_numbers on {:?} for dd account failed: {}",
                    client,
                    e
                )
            })?[0];
        let designated_dealer_account = LocalAccount::new(address, account_key, sequence_number);

        let mut versions = HashMap::new();
        let base_version = Version::new(0, base_image_tag.to_string());
        let cur_version = Version::new(1, image_tag.to_string());
        versions.insert(cur_version, image_tag.to_string());
        versions.insert(base_version, base_image_tag.to_string());

        Ok(Self {
            validators,
            fullnodes,
            root_account,
            treasury_compliance_account,
            designated_dealer_account,
            kube_client,
            chain_id: ChainId::new(NamedChain::DEVNET.id()),
            cluster_name: cluster_name.to_string(),
            helm_repo: helm_repo.to_string(),
            versions: Arc::new(versions),
        })
    }

    fn get_url(&self) -> String {
        self.validators
            .values()
            .next()
            .unwrap()
            .json_rpc_endpoint()
            .to_string()
    }

    #[allow(dead_code)]
    fn get_kube_client(&self) -> K8sClient {
        self.kube_client.clone()
    }
}

impl Drop for K8sSwarm {
    // When the K8sSwarm struct goes out of scope we need to wipe the chain state and scale down
    fn drop(&mut self) {
        uninstall_from_k8s_cluster().unwrap();
        set_eks_nodegroup_size(self.cluster_name.clone(), 0, true).unwrap();
    }
}

impl Swarm for K8sSwarm {
    fn health_check(&mut self) -> Result<()> {
        nodes_healthcheck(Box::new(
            self.validators
                .values_mut()
                .map(|v| v as &mut dyn Validator),
        ))
    }

    fn validators<'a>(&'a self) -> Box<dyn Iterator<Item = &'a dyn Validator> + 'a> {
        Box::new(self.validators.values().map(|v| v as &'a dyn Validator))
    }

    fn validators_mut<'a>(&'a mut self) -> Box<dyn Iterator<Item = &'a mut dyn Validator> + 'a> {
        Box::new(
            self.validators
                .values_mut()
                .map(|v| v as &'a mut dyn Validator),
        )
    }

    fn validator(&self, id: PeerId) -> Option<&dyn Validator> {
        self.validators.get(&id).map(|v| v as &dyn Validator)
    }

    fn validator_mut(&mut self, id: PeerId) -> Option<&mut dyn Validator> {
        self.validators
            .get_mut(&id)
            .map(|v| v as &mut dyn Validator)
    }

    fn upgrade_validator(&mut self, id: PeerId, version: &Version) -> Result<()> {
        let validator = self
            .validators
            .get_mut(&id)
            .ok_or_else(|| anyhow!("Invalid id: {}", id))?;
        let version = self
            .versions
            .get(version)
            .cloned()
            .ok_or_else(|| anyhow!("Invalid version: {:?}", version))?;
        set_validator_image_tag(validator.name(), &version, &self.helm_repo)
    }

    fn full_nodes<'a>(&'a self) -> Box<dyn Iterator<Item = &'a dyn FullNode> + 'a> {
        Box::new(self.fullnodes.values().map(|v| v as &'a dyn FullNode))
    }

    fn full_nodes_mut<'a>(&'a mut self) -> Box<dyn Iterator<Item = &'a mut dyn FullNode> + 'a> {
        Box::new(
            self.fullnodes
                .values_mut()
                .map(|v| v as &'a mut dyn FullNode),
        )
    }

    fn full_node(&self, id: PeerId) -> Option<&dyn FullNode> {
        self.fullnodes.get(&id).map(|v| v as &dyn FullNode)
    }

    fn full_node_mut(&mut self, id: PeerId) -> Option<&mut dyn FullNode> {
        self.fullnodes.get_mut(&id).map(|v| v as &mut dyn FullNode)
    }

    fn add_validator(&mut self, _version: &Version, _template: NodeConfig) -> Result<PeerId> {
        todo!()
    }

    fn remove_validator(&mut self, id: PeerId) -> Result<()> {
        remove_helm_release(self.validator(id).unwrap().name())
    }

    fn add_full_node(&mut self, _version: &Version, _template: NodeConfig) -> Result<PeerId> {
        todo!()
    }

    fn remove_full_node(&mut self, _id: PeerId) -> Result<()> {
        todo!()
    }

    fn versions<'a>(&'a self) -> Box<dyn Iterator<Item = Version> + 'a> {
        Box::new(self.versions.keys().cloned())
    }

    fn chain_info(&mut self) -> ChainInfo<'_> {
        let url = self.get_url();
        ChainInfo::new(
            &mut self.root_account,
            &mut self.treasury_compliance_account,
            &mut self.designated_dealer_account,
            url,
            self.chain_id,
        )
    }

    // Returns env CENTRAL_LOGGING_ADDRESS if present (without timestamps)
    // otherwise returns a kubectl logs command to retrieve the logs manually
    fn logs_location(&mut self) -> String {
        if let Ok(central_logging_address) = std::env::var("CENTRAL_LOGGING_ADDRESS") {
            central_logging_address
        } else {
            let hostname_output = Command::new("hostname")
                .output()
                .expect("failed to get pod hostname");
            let hostname = String::from_utf8(hostname_output.stdout).unwrap();
            format!(
                "aws eks --region us-west-2 update-kubeconfig --name {} && kubectl logs {}",
                &self.cluster_name, hostname
            )
        }
    }
}

pub(crate) fn k8s_retry_strategy() -> impl Iterator<Item = Duration> {
    diem_retrier::exp_retry_strategy(1000, 5000, 30)
}

#[derive(Clone, Debug)]
pub struct KubeService {
    pub name: String,
    pub host_ip: String,
}

impl TryFrom<Service> for KubeService {
    type Error = anyhow::Error;

    fn try_from(service: Service) -> Result<Self, Self::Error> {
        let metadata = service.metadata;
        let name = metadata
            .name
            .ok_or_else(|| format_err!("node name not found"))?;
        let spec = service
            .spec
            .ok_or_else(|| format_err!("spec not found for node"))?;
        let host_ip = spec.cluster_ip.unwrap_or_default();
        Ok(Self { name, host_ip })
    }
}

async fn list_services(client: K8sClient) -> Result<Vec<KubeService>> {
    let node_api: Api<Service> = Api::all(client);
    let lp = ListParams::default();
    let services = node_api.list(&lp).await?.items;
    services.into_iter().map(KubeService::try_from).collect()
}

pub(crate) async fn get_validators(
    client: K8sClient,
    image_tag: &str,
) -> Result<HashMap<PeerId, K8sNode>> {
    let services = list_services(client).await?;
    services
        .into_iter()
        .filter(|s| s.name.contains(VALIDATOR_LB))
        .map(|s| {
            let node_id = parse_node_id(&s.name).expect("error to parse node id");
            let node = K8sNode {
                name: format!("val{}", node_id),
                // TODO: fetch this from running node
                peer_id: PeerId::random(),
                node_id,
                ip: s.host_ip.clone(),
                port: JSON_RPC_PORT,
                dns: s.name,
                version: Version::new(0, image_tag.to_string()),
                runtime: Runtime::new().unwrap(),
            };
            Ok((node.peer_id(), node))
        })
        .collect::<Result<HashMap<_, _>>>()
}

fn parse_node_id(s: &str) -> Result<usize> {
    let v = s.split('-').collect::<Vec<&str>>();
    if v.len() < 5 {
        return Err(format_err!("Failed to parse {:?} node id format", s));
    }
    let idx: usize = v[0][3..].parse().unwrap();
    Ok(idx)
}

fn load_root_key(root_key_bytes: &[u8]) -> Ed25519PrivateKey {
    Ed25519PrivateKey::try_from(root_key_bytes).unwrap()
}

fn load_tc_key(tc_key_bytes: &[u8]) -> Ed25519PrivateKey {
    Ed25519PrivateKey::try_from(tc_key_bytes).unwrap()
}

pub fn nodes_healthcheck<'a>(
    nodes: Box<dyn Iterator<Item = &'a mut dyn Validator> + 'a>,
) -> Result<()> {
    let unhealthy_nodes = nodes
        .filter_map(|node| {
            let node_name = node.name().to_string();
            println!("Attempting health check: {}", node_name);
            // perform healthcheck with retry, returning unhealthy
            let check = diem_retrier::retry(k8s_retry_strategy(), || match node.health_check() {
                Ok(_) => {
                    println!("Node {} healthy", node_name);
                    Ok(())
                }
                Err(ref x) => {
                    debug!("Node {} unhealthy: {}", node_name, x);
                    Err(())
                }
            });
            if check.is_err() {
                return Some(node_name);
            }
            None
        })
        .collect::<Vec<_>>();
    if !unhealthy_nodes.is_empty() {
        bail!("Unhealthy validators after cleanup: {:?}", unhealthy_nodes);
    }
    println!("All validators healthy after cleanup!");
    println!("Wait for the instance to sync up with peers");
    thread::sleep(Duration::from_secs(20));

    Ok(())
}
<|endoftext|>


<commit_before>use std::error::Error;
use std::path::{Path, Component};
use iron::prelude::*;
use iron::middleware::Handler;
use iron::{Url,status};
use iron::typemap;
use sequence_trie::SequenceTrie;
use std::fmt;

/// Exposes the original, unmodified path to be stored in `Request::extensions`.
#[derive(Copy, Clone)]
pub struct OriginalUrl;
impl typemap::Key for OriginalUrl { type Value = Url; }

/// `Mount` is a simple mounting middleware.
///
/// Mounting allows you to install a handler on a route and have it receive requests as if they
/// are relative to that route. For example, a handler mounted on `/foo/` will receive
/// requests like `/foo/bar` as if they are just `/bar`. Iron's mounting middleware allows
/// you to specify multiple mountings using one middleware instance. Requests that pass through
/// the mounting middleware are passed along to the mounted handler that best matches the request's
/// path. `Request::url` is modified so that requests appear to be relative to the mounted handler's route.
///
/// Mounted handlers may also access the *original* URL by requesting the `OriginalUrl` key
/// from `Request::extensions`.
pub struct Mount {
    inner: SequenceTrie<String, Match>
}

struct Match {
    handler: Box<Handler>,
    length: usize
}

/// The error returned by `Mount` when a request doesn't match any mounted handlers.
#[derive(Debug)]
pub struct NoMatch;

impl Error for NoMatch {
    fn description(&self) -> &'static str { "No Match" }
}

impl fmt::Display for NoMatch {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(self.description())
    }
}

impl Mount {
    /// Creates a new instance of `Mount`.
    pub fn new() -> Mount {
        Mount {
            inner: SequenceTrie::new()
        }
    }

    /// Mounts a given `Handler` onto a route.
    ///
    /// This method may be called multiple times with different routes.
    /// For a given request, the *most specific* handler will be selected.
    ///
    /// Existing handlers on the same route will be overwritten.
    pub fn mount<H: Handler>(&mut self, route: &str, handler: H) -> &mut Mount {
        // Parse the route into a list of strings. The unwrap is safe because strs are UTF-8.
        let key: Vec<String> = Path::new(route).components().flat_map(|c|
            match c {
                Component::RootDir => None,
                c => Some(c.as_os_str().to_str().unwrap().to_string())
            }.into_iter()
        ).collect();

        // Insert a match struct into the trie.
        self.inner.insert(key.as_ref(), Match {
            handler: Box::new(handler) as Box<Handler>,
            length: key.len()
        });
        self
    }
}

impl Handler for Mount {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        // Find the matching handler.
        let matched = {
            // Extract the request path.
            let path = req.url.path();

            // If present, remove the trailing empty string (which represents a trailing slash).
            // If it isn't removed the path will never match anything, because
            // Path::str_components ignores trailing slashes and will never create routes
            // ending in "".
            let key = match path.last() {
                Some(s) if s.is_empty() => &path[..path.len() - 1],
                _ => &path
            };

            let key=key.into_iter().map(|s|String::from(*s)).collect::<Vec<String>>();

            // Search the Trie for the nearest most specific match.
            match self.inner.get_ancestor(&key) {
                Some(matched) => matched,
                None => return Err(IronError::new(NoMatch, status::NotFound))
            }
        };

        // We have a match, so fire off the child.
        // If another mount middleware hasn't already, insert the unmodified url
        // into the extensions as the "original url".
        let is_outer_mount = !req.extensions.contains::<OriginalUrl>();
        if is_outer_mount {
            req.extensions.insert::<OriginalUrl>(req.url.clone());
        }

        // Remove the prefix from the request's path before passing it to the mounted handler.
        // If the prefix is entirely removed and no trailing slash was present, the new path
        // will be the empty list. For the purposes of redirection, conveying that the path
        // did not include a trailing slash is more important than providing a non-empty list.
        //req.url.path() = req.url.path()[matched.length..].to_vec();
        req.url.path().clone_from(&req.url.path()[matched.length..].to_vec());
        let res = matched.handler.handle(req);

        // Reverse the URL munging, for future middleware.
        req.url = match req.extensions.get::<OriginalUrl>() {
            Some(original) => original.clone(),
            None => panic!("OriginalUrl unexpectedly removed from req.extensions.")
        };

        // If this mount middleware is the outermost mount middleware,
        // remove the original url from the extensions map to prevent leakage.
        if is_outer_mount {
            req.extensions.remove::<OriginalUrl>();
        }

        res
    }
}

<commit_msg>Normalize code style<commit_after>use std::error::Error;
use std::path::{Path, Component};
use iron::prelude::*;
use iron::middleware::Handler;
use iron::{status, Url};
use iron::typemap;
use sequence_trie::SequenceTrie;
use std::fmt;

/// Exposes the original, unmodified path to be stored in `Request::extensions`.
#[derive(Copy, Clone)]
pub struct OriginalUrl;
impl typemap::Key for OriginalUrl { type Value = Url; }

/// `Mount` is a simple mounting middleware.
///
/// Mounting allows you to install a handler on a route and have it receive requests as if they
/// are relative to that route. For example, a handler mounted on `/foo/` will receive
/// requests like `/foo/bar` as if they are just `/bar`. Iron's mounting middleware allows
/// you to specify multiple mountings using one middleware instance. Requests that pass through
/// the mounting middleware are passed along to the mounted handler that best matches the request's
/// path. `Request::url` is modified so that requests appear to be relative to the mounted handler's route.
///
/// Mounted handlers may also access the *original* URL by requesting the `OriginalUrl` key
/// from `Request::extensions`.
pub struct Mount {
    inner: SequenceTrie<String, Match>
}

struct Match {
    handler: Box<Handler>,
    length: usize
}

/// The error returned by `Mount` when a request doesn't match any mounted handlers.
#[derive(Debug)]
pub struct NoMatch;

impl Error for NoMatch {
    fn description(&self) -> &'static str { "No Match" }
}

impl fmt::Display for NoMatch {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(self.description())
    }
}

impl Mount {
    /// Creates a new instance of `Mount`.
    pub fn new() -> Mount {
        Mount {
            inner: SequenceTrie::new()
        }
    }

    /// Mounts a given `Handler` onto a route.
    ///
    /// This method may be called multiple times with different routes.
    /// For a given request, the *most specific* handler will be selected.
    ///
    /// Existing handlers on the same route will be overwritten.
    pub fn mount<H: Handler>(&mut self, route: &str, handler: H) -> &mut Mount {
        // Parse the route into a list of strings. The unwrap is safe because strs are UTF-8.
        let key: Vec<String> = Path::new(route).components().flat_map(|c|
            match c {
                Component::RootDir => None,
                c => Some(c.as_os_str().to_str().unwrap().to_string())
            }.into_iter()
        ).collect();

        // Insert a match struct into the trie.
        self.inner.insert(key.as_ref(), Match {
            handler: Box::new(handler) as Box<Handler>,
            length: key.len()
        });
        self
    }
}

impl Handler for Mount {
    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        // Find the matching handler.
        let matched = {
            // Extract the request path.
            let path = req.url.path();

            // If present, remove the trailing empty string (which represents a trailing slash).
            // If it isn't removed the path will never match anything, because
            // Path::str_components ignores trailing slashes and will never create routes
            // ending in "".
            let key = match path.last() {
                Some(s) if s.is_empty() => &path[..path.len() - 1],
                _ => &path
            };

            let key: Vec<_> = key.into_iter().map(|s| String::from(*s)).collect();

            // Search the Trie for the nearest most specific match.
            match self.inner.get_ancestor(&key) {
                Some(matched) => matched,
                None => return Err(IronError::new(NoMatch, status::NotFound))
            }
        };

        // We have a match, so fire off the child.
        // If another mount middleware hasn't already, insert the unmodified url
        // into the extensions as the "original url".
        let is_outer_mount = !req.extensions.contains::<OriginalUrl>();
        if is_outer_mount {
            req.extensions.insert::<OriginalUrl>(req.url.clone());
        }

        // Remove the prefix from the request's path before passing it to the mounted handler.
        // If the prefix is entirely removed and no trailing slash was present, the new path
        // will be the empty list. For the purposes of redirection, conveying that the path
        // did not include a trailing slash is more important than providing a non-empty list.
        req.url.path().clone_from(&req.url.path()[matched.length..].to_vec());
        let res = matched.handler.handle(req);

        // Reverse the URL munging, for future middleware.
        req.url = match req.extensions.get::<OriginalUrl>() {
            Some(original) => original.clone(),
            None => panic!("OriginalUrl unexpectedly removed from req.extensions.")
        };

        // If this mount middleware is the outermost mount middleware,
        // remove the original url from the extensions map to prevent leakage.
        if is_outer_mount {
            req.extensions.remove::<OriginalUrl>();
        }

        res
    }
}

<|endoftext|>


<commit_before><commit_msg>change test expectation<commit_after><|endoftext|>


<commit_before>use core::ops::{BitXorAssign, MulAssign};
use byteorder::{BigEndian, ByteOrder};

pub(crate) fn ghash(key: &[u8; 16], data: &[u8], ciphertext: &[u8]) -> [u8; 16] {
    let mut tag = [0; 16];
    let mut mac = GHash::new(key, data);
    mac.update(ciphertext);
    mac.write_tag(&mut tag);
    tag
}

const R0: u64 = 0xe1 << 56;

struct GHash {
    function: PolyFunction,
    data_len: u64,
    ciphertext_len: u64,
}

impl GHash {
    fn new(key: &[u8; 16], data: &[u8]) -> Self {
        let mut ghash = Self {
            function: PolyFunction::new(key),
            data_len: data.len() as u64,
            ciphertext_len: 0,
        };
        ghash.process(data);
        ghash
    }

    fn update(&mut self, input: &[u8]) {
        self.ciphertext_len += input.len() as u64;
        self.process(input);
    }

    fn write_tag(mut self, output: &mut [u8; 16]) {
        BigEndian::write_u64(&mut output[..8], 8 * self.data_len);
        BigEndian::write_u64(&mut output[8..], 8 * self.ciphertext_len);
        self.function.process(output);
        self.function.write_value(output);
    }

    fn process(&mut self, input: &[u8]) {
        for chunk in input.chunks(16) {
            if chunk.len() < 16 {
                let buffer = &mut [0; 16];
                buffer[..chunk.len()].copy_from_slice(chunk);
                self.function.process(buffer);
            } else {
                self.function.process(chunk);
            }
        }
    }
}

#[derive(Clone, Copy)]
struct GFBlock([u64; 2]);

struct PolyFunction {
    key_block: GFBlock,
    state: GFBlock,
}

impl PolyFunction {
    fn new(key: &[u8; 16]) -> Self {
        Self {
            key_block: GFBlock::new(key),
            state: GFBlock([0; 2]),
        }
    }

    fn process(&mut self, input: &[u8]) {
        self.state ^= GFBlock::new(input);
        self.state *= self.key_block;
    }

    fn write_value(self, output: &mut [u8; 16]) {
        BigEndian::write_u64_into(&self.state.0, output);
    }
}

impl GFBlock {
    fn new(bytes: &[u8]) -> Self {
        let mut block = [0; 2];
        BigEndian::read_u64_into(bytes, &mut block);
        GFBlock(block)
    }
}

impl BitXorAssign for GFBlock {
    fn bitxor_assign(&mut self, rhs: Self) {
        for (l, r) in self.0.iter_mut().zip(&rhs.0) {
            *l ^= r;
        }
    }
}

impl MulAssign for GFBlock {
    fn mul_assign(&mut self, rhs: Self) {
        let mut z = GFBlock([0; 2]);
        let mut v = rhs;
        for xp in &mut self.0 {
            for _ in 0..64 {
                let mut h = *xp & (1 << 63);
                let mut m = (h as i64 >> 63) as u64;
                for (l, r) in z.0.iter_mut().zip(&v.0) {
                    *l ^= r & m;
                }

                h = v.0[1] << 63;
                m = (h as i64 >> 7) as u64;
                v.0[1] >>= 1;
                v.0[1] |= v.0[0] << 63;
                v.0[0] >>= 1;
                v.0[0] ^= R0 & m;
                *xp <<= 1;
            }
        }
        self.0 = z.0;
    }
}

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

    #[test]
    fn test_case_1_2() {
        let h = &mut [0; 16];
        h.copy_from_slice(&h2b("66e94bd4ef8a2c3b884cfa59ca342b2e"));
        assert_eq!([0; 16], ghash(h, &[], &[]));

        let c = &h2b("0388dace60b6a392f328c2b971b2fe78");
        let expected = h2b("f38cbb1ad69223dcc3457ae5b6b0f885");
        assert_eq!(expected, ghash(h, &[], c));
    }

    #[test]
    fn test_case_15_16_17_18() {
        let h = &mut [0; 16];
        h.copy_from_slice(&h2b("acbef20579b4b8ebce889bac8732dad7"));

        let c = &h2b(
            "522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa\
             8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad",
        );
        let expected = h2b("4db870d37cb75fcb46097c36230d1612");
        assert_eq!(expected, ghash(h, &[], c));

        let a = &h2b("feedfacedeadbeeffeedfacedeadbeefabaddad2");
        let c = &c[..60];
        let expected = h2b("8bd0c4d8aacd391e67cca447e8c38f65");
        assert_eq!(expected, ghash(h, a, c));

        let c = &h2b(
            "c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0\
             feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f",
        );
        let expected = h2b("75a34288b8c68f811c52b2e9a2f97f63");
        assert_eq!(expected, ghash(h, a, c));

        let c = &h2b(
            "5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf4\
             0fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f",
        );
        let expected = h2b("d5ffcf6fc5ac4d69722187421a7f170b");
        assert_eq!(expected, ghash(h, a, c));
    }
}
<commit_msg>ghash: refactor tests<commit_after>use core::ops::{BitXorAssign, MulAssign};
use byteorder::{BigEndian, ByteOrder};

pub(crate) fn ghash(key: &[u8; 16], data: &[u8], ciphertext: &[u8]) -> [u8; 16] {
    let mut tag = [0; 16];
    let mut mac = GHash::new(key, data);
    mac.update(ciphertext);
    mac.write_tag(&mut tag);
    tag
}

const R0: u64 = 0xe1 << 56;

struct GHash {
    function: PolyFunction,
    data_len: u64,
    ciphertext_len: u64,
}

impl GHash {
    fn new(key: &[u8; 16], data: &[u8]) -> Self {
        let mut ghash = Self {
            function: PolyFunction::new(key),
            data_len: data.len() as u64,
            ciphertext_len: 0,
        };
        ghash.process(data);
        ghash
    }

    fn update(&mut self, input: &[u8]) {
        self.ciphertext_len += input.len() as u64;
        self.process(input);
    }

    fn write_tag(mut self, output: &mut [u8; 16]) {
        BigEndian::write_u64(&mut output[..8], 8 * self.data_len);
        BigEndian::write_u64(&mut output[8..], 8 * self.ciphertext_len);
        self.function.process(output);
        self.function.write_value(output);
    }

    fn process(&mut self, input: &[u8]) {
        for chunk in input.chunks(16) {
            if chunk.len() < 16 {
                let buffer = &mut [0; 16];
                buffer[..chunk.len()].copy_from_slice(chunk);
                self.function.process(buffer);
            } else {
                self.function.process(chunk);
            }
        }
    }
}

#[derive(Clone, Copy)]
struct GFBlock([u64; 2]);

struct PolyFunction {
    key_block: GFBlock,
    state: GFBlock,
}

impl PolyFunction {
    fn new(key: &[u8; 16]) -> Self {
        Self {
            key_block: GFBlock::new(key),
            state: GFBlock([0; 2]),
        }
    }

    fn process(&mut self, input: &[u8]) {
        self.state ^= GFBlock::new(input);
        self.state *= self.key_block;
    }

    fn write_value(self, output: &mut [u8; 16]) {
        BigEndian::write_u64_into(&self.state.0, output);
    }
}

impl GFBlock {
    fn new(bytes: &[u8]) -> Self {
        let mut block = [0; 2];
        BigEndian::read_u64_into(bytes, &mut block);
        GFBlock(block)
    }
}

impl BitXorAssign for GFBlock {
    fn bitxor_assign(&mut self, rhs: Self) {
        for (l, r) in self.0.iter_mut().zip(&rhs.0) {
            *l ^= r;
        }
    }
}

impl MulAssign for GFBlock {
    fn mul_assign(&mut self, rhs: Self) {
        let mut z = GFBlock([0; 2]);
        let mut v = rhs;
        for xp in &mut self.0 {
            for _ in 0..64 {
                let mut h = *xp & (1 << 63);
                let mut m = (h as i64 >> 63) as u64;
                for (l, r) in z.0.iter_mut().zip(&v.0) {
                    *l ^= r & m;
                }

                h = v.0[1] << 63;
                m = (h as i64 >> 7) as u64;
                v.0[1] >>= 1;
                v.0[1] |= v.0[0] << 63;
                v.0[0] >>= 1;
                v.0[0] ^= R0 & m;
                *xp <<= 1;
            }
        }
        self.0 = z.0;
    }
}

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

    fn check(expected: &str, h: &str, a: &str, c: &str) {
        let h_vec = &h2b(h);
        let h = &mut [0; 16];
        h.copy_from_slice(h_vec);
        let a = &h2b(a);
        let c = &h2b(c);
        let expected = h2b(expected);
        assert_eq!(expected, ghash(h, a, c));
    }

    #[test]
    fn test_case_1_2() {
        let h = "66e94bd4ef8a2c3b884cfa59ca342b2e";
        let a = "";
        let c = "";
        let expected = "00000000000000000000000000000000";
        check(expected, h, a, c);

        let c = "0388dace60b6a392f328c2b971b2fe78";
        let expected = "f38cbb1ad69223dcc3457ae5b6b0f885";
        check(expected, h, a, c);
    }

    #[test]
    fn test_case_15_16_17_18() {
        let h = "acbef20579b4b8ebce889bac8732dad7";
        let a = "";
        let c = "522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa\
                 8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad";
        let expected = "4db870d37cb75fcb46097c36230d1612";
        check(expected, h, a, c);

        let a = "feedfacedeadbeeffeedfacedeadbeefabaddad2";
        let c = &c[..120];
        let expected = "8bd0c4d8aacd391e67cca447e8c38f65";
        check(expected, h, a, c);

        let c = "c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0\
                 feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f";
        let expected = "75a34288b8c68f811c52b2e9a2f97f63";
        check(expected, h, a, c);

        let c = "5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf4\
                 0fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f";
        let expected = "d5ffcf6fc5ac4d69722187421a7f170b";
        check(expected, h, a, c);
    }
}
<|endoftext|>


<commit_before>//! Glyph caching

extern crate freetype as ft;

use std::path::Path;
use std::collections::hash_map::{ HashMap, Entry };
use graphics::character::{ CharacterCache, Character };
use graphics::types::FontSize;
use self::ft::render_mode::RenderMode;
use { gfx, Texture, TextureSettings };

/// An enum to represent various possible run-time errors that may occur.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Error {
    /// An error happened when creating a gfx texture.
    Texture(gfx::tex::TextureError),
    /// An error happened with the FreeType library.
    Freetype(ft::error::Error)
}

impl From<gfx::tex::TextureError> for Error {
    fn from(tex_err: gfx::tex::TextureError) -> Self {
        Error::Texture(tex_err)
    }
}

impl From<ft::error::Error> for Error {
    fn from(ft_err: ft::error::Error) -> Self {
        Error::Freetype(ft_err)
    }
}

/// A struct used for caching rendered font.
pub struct GlyphCache<R, F> where R: gfx::Resources {
    /// The font face.
    pub face: ft::Face<'static>,
    factory: F,
    data: HashMap<(FontSize, char), Character<Texture<R>>>
}

impl<R, F> GlyphCache<R, F> where R: gfx::Resources {
     /// Constructor for a GlyphCache.
    pub fn new<P>(font: P, factory: F) -> Result<Self, Error>
        where P: AsRef<Path>
    {
        let freetype = try!(ft::Library::init());
        let face = try!(freetype.new_face(font.as_ref(), 0));
        Ok(GlyphCache {
            face: face,
            factory: factory,
            data: HashMap::new(),
        })
    }
}

impl<R, F> CharacterCache for GlyphCache<R, F> where
    R: gfx::Resources,
    F: gfx::Factory<R>,
{
    type Texture = Texture<R>;

    fn character(&mut self, size: FontSize, ch: char) -> &Character<Self::Texture> {
        match self.data.entry((size, ch)) {
            //returning `into_mut()' to get reference with 'a lifetime
            Entry::Occupied(v) => v.into_mut(),
            Entry::Vacant(v) => {
                self.face.set_pixel_sizes(0, size).unwrap();
                self.face.load_char(ch as usize, ft::face::DEFAULT).unwrap();
                let glyph = self.face.glyph().get_glyph().unwrap();
                let bitmap_glyph = glyph.to_bitmap(RenderMode::Normal, None).unwrap();
                let glyph_size = glyph.advance();
                v.insert(Character {
                    offset: [
                        bitmap_glyph.left() as f64,
                        bitmap_glyph.top() as f64
                    ],
                    size: [
                        (glyph_size.x >> 16) as f64,
                        (glyph_size.y >> 16) as f64
                    ],
                    texture: {
                        let bitmap = bitmap_glyph.bitmap();
                        if bitmap.width() == 0 || bitmap.rows() == 0 {
                            Texture::empty(&mut self.factory)
                                    .unwrap()
                        }else {
                            Texture::from_memory_alpha(
                                &mut self.factory,
                                bitmap.buffer(),
                                bitmap.width() as u32,
                                bitmap.rows() as u32,
                                &TextureSettings::new()
                            ).unwrap()
                        }
                    },
                })
            }
        }
    }
}
<commit_msg>Fix errors<commit_after>//! Glyph caching

extern crate freetype as ft;

use std::path::Path;
use std::collections::hash_map::{ HashMap, Entry };
use graphics::character::{ CharacterCache, Character };
use graphics::types::FontSize;
use self::ft::render_mode::RenderMode;
use { gfx, Texture, TextureSettings };

/// An enum to represent various possible run-time errors that may occur.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Error {
    /// An error happened when creating a gfx texture.
    Texture(gfx::tex::TextureError),
    /// An error happened with the FreeType library.
    Freetype(ft::error::Error)
}

impl From<gfx::tex::TextureError> for Error {
    fn from(tex_err: gfx::tex::TextureError) -> Self {
        Error::Texture(tex_err)
    }
}

impl From<ft::error::Error> for Error {
    fn from(ft_err: ft::error::Error) -> Self {
        Error::Freetype(ft_err)
    }
}

/// A struct used for caching rendered font.
pub struct GlyphCache<R, F> where R: gfx::Resources {
    /// The font face.
    pub face: ft::Face<'static>,
    factory: F,
    data: HashMap<(FontSize, char), Character<Texture<R>>>
}

impl<R, F> GlyphCache<R, F> where R: gfx::Resources {
     /// Constructor for a GlyphCache.
    pub fn new<P>(font: P, factory: F) -> Result<Self, Error>
        where P: AsRef<Path>
    {
        let freetype = try!(ft::Library::init());
        let face = try!(freetype.new_face(font.as_ref(), 0));
        Ok(GlyphCache {
            face: face,
            factory: factory,
            data: HashMap::new(),
        })
    }
}

impl<R, F> CharacterCache for GlyphCache<R, F> where
    R: gfx::Resources,
    F: gfx::Factory<R>,
{
    type Texture = Texture<R>;

    fn character(&mut self, size: FontSize, ch: char) -> &Character<Self::Texture> {
        match self.data.entry((size, ch)) {
            //returning `into_mut()' to get reference with 'a lifetime
            Entry::Occupied(v) => v.into_mut(),
            Entry::Vacant(v) => {
                self.face.set_pixel_sizes(0, size).unwrap();
                self.face.load_char(ch as usize, ft::face::DEFAULT).unwrap();
                let glyph = self.face.glyph().get_glyph().unwrap();
                let bitmap_glyph = glyph.to_bitmap(RenderMode::Normal, None).unwrap();
                let glyph_size = [glyph.advance_x(), glyph.advance_y()];
                v.insert(Character {
                    offset: [
                        bitmap_glyph.left() as f64,
                        bitmap_glyph.top() as f64
                    ],
                    size: [
                        (glyph_size[0] >> 16) as f64,
                        (glyph_size[1] >> 16) as f64
                    ],
                    texture: {
                        let bitmap = bitmap_glyph.bitmap();
                        if bitmap.width() == 0 || bitmap.rows() == 0 {
                            Texture::empty(&mut self.factory)
                                    .unwrap()
                        }else {
                            Texture::from_memory_alpha(
                                &mut self.factory,
                                bitmap.buffer(),
                                bitmap.width() as u32,
                                bitmap.rows() as u32,
                                &TextureSettings::new()
                            ).unwrap()
                        }
                    },
                })
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::hash::{Hash};
use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::RingBuf;
use std::iter::Map;
use std::collections::hash_map::{
    Keys,
    Occupied,
    Vacant,
};
use std::slice::{
    Items,
};
use std::fmt;

/// **Graph\<N, E\>** is a regular graph, with generic node values **N** and edge weights **E**.
///
/// It uses an adjacency list representation, i.e. using *O(|V| + |E|)* space.
///
/// The node type must be suitable as a hash table key (Implementing **Eq + Hash**)
/// as well as being a simple type.
///
/// The node type must implement **PartialOrd** so that the implementation can
/// properly order the pair (**a**, **b**) for an edge connecting any two nodes **a** and **b**.
#[deriving(Clone)]
pub struct Graph<N: Eq + Hash, E> {
    nodes: HashMap<N, Vec<N>>,
    edges: HashMap<(N, N), E>,
}

impl<N: Eq + Hash + fmt::Show, E: fmt::Show> fmt::Show for Graph<N, E>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.nodes.fmt(f)
    }
}

#[inline]
fn edge_key<N: Copy + PartialOrd>(a: N, b: N) -> (N, N)
{
    if a <= b { (a, b) } else { (b, a) }
}

#[inline]
fn copy<N: Copy>(n: &N) -> N { *n }

impl<N, E> Graph<N, E> where N: Copy + PartialOrd + Eq + Hash
{
    /// Create a new **Graph**.
    pub fn new() -> Graph<N, E>
    {
        Graph {
            nodes: HashMap::new(),
            edges: HashMap::new(),
        }
    }

    /// Add node **n** to the graph.
    pub fn add_node(&mut self, n: N) -> N {
        match self.nodes.entry(n) {
            Occupied(_) => {}
            Vacant(ent) => { ent.set(Vec::new()); }
        }
        n
    }

    /// Return **true** if node **n** was removed.
    pub fn remove_node(&mut self, n: N) -> bool {
        let successors = match self.nodes.remove(&n) {
            None => return false,
            Some(sus) => sus,
        };
        for succ in successors.into_iter() {
            // remove all successor links
            self.remove_single_edge(&succ, &n);
            // Remove all edge values
            self.edges.remove(&edge_key(n, succ));
        }
        true
    }

    /// Return **true** if the node is contained in the graph.
    pub fn contains_node(&self, n: N) -> bool {
        self.nodes.contains_key(&n)
    }

    /// Add an edge connecting **a** and **b** to the graph.
    ///
    /// Return **true** if edge did not previously exist.
    pub fn add_edge(&mut self, a: N, b: N, edge: E) -> bool
    {
        // Use PartialOrd to order the edges
        match self.nodes.entry(a) {
            Occupied(ent) => { ent.into_mut().push(b); }
            Vacant(ent) => { ent.set(vec![b]); }
        }
        match self.nodes.entry(b) {
            Occupied(ent) => { ent.into_mut().push(a); }
            Vacant(ent) => { ent.set(vec![a]); }
        }
        self.edges.insert(edge_key(a, b), edge).is_none()
    }

    /// Remove successor relation from a to b
    fn remove_single_edge(&mut self, a: &N, b: &N) {
        match self.nodes.get_mut(a) {
            None => {}
            Some(sus) => {
                match sus.iter().position(|elt| elt == b) {
                    Some(index) => { sus.swap_remove(index); }
                    None => {}
                }
            }
        }
    }

    /// Remove edge from **a** to **b** from the graph.
    ///
    /// Return **None** if the edge didn't exist.
    pub fn remove_edge(&mut self, a: N, b: N) -> Option<E>
    {
        self.remove_single_edge(&a, &b);
        self.remove_single_edge(&b, &a);
        self.edges.remove(&edge_key(a, b))
    }

    /// Return **true** if the edge connecting **a** with **b** is contained in the graph.
    pub fn contains_edge(&self, a: N, b: N) -> bool {
        self.edges.contains_key(&edge_key(a, b))
    }

    /// Return an iterator over the nodes of the graph.
    ///
    /// Iterator element type is **&'a N**.
    pub fn nodes<'a>(&'a self) -> Nodes<'a, N>
    {
        Nodes{iter: self.nodes.keys()}
    }

    /// Return an iterator over the nodes that are connected with **from** by edges.
    ///
    /// If the node **from** does not exist in the graph, return an empty iterator.
    ///
    /// Iterator element type is **N**.
    pub fn neighbors<'a>(&'a self, from: N) -> Neighbors<'a, N>
    {
        Neighbors{iter:
            match self.nodes.get(&from) {
                Some(neigh) => neigh.iter(),
                None => [].iter(),
            }.map(copy)
        }
    }

    /// Return an iterator over the nodes that are connected with **from** by edges,
    /// paired with the edge weight.
    ///
    /// If the node **from** does not exist in the graph, return an empty iterator.
    ///
    /// Iterator element type is **(N, &'a E)**.
    pub fn edges<'a>(&'a self, from: N) -> Edges<'a, N, E>
    {
        Edges {
            from: from,
            iter: self.neighbors(from),
            edges: &self.edges,
        }
    }

    /// Return a reference to the edge weight connecting **a** with **b**, or
    /// **None** if the edge does not exist in the graph.
    pub fn edge<'a>(&'a self, a: N, b: N) -> Option<&'a E>
    {
        self.edges.get(&edge_key(a, b))
    }

    /// Return a mutable reference to the edge weight connecting **a** with **b**, or
    /// **None** if the edge does not exist in the graph.
    pub fn edge_mut<'a>(&'a mut self, a: N, b: N) -> Option<&'a mut E>
    {
        self.edges.get_mut(&edge_key(a, b))
    }

    pub fn traverse_breadth_first(&self, start: N) -> BreadthFirstTraversal<N, E>
    {
        BreadthFirstTraversal{
            graph: self,
            stack: {
                let mut stack = RingBuf::new();
                stack.push_back(start);
                stack
            },
            visited: HashSet::new(),
        }
    }

    pub fn traverse_depth_first(&self, start: N) -> DepthFirstTraversal<N, E>
    {
        DepthFirstTraversal{
            graph: self,
            stack: vec![start],
            visited: HashSet::new(),
        }
    }
}

macro_rules! iterator_methods(
    ($elt_type:ty) => (
        #[inline]
        fn next(&mut self) -> Option<$elt_type>
        {
            self.iter.next()
        }

        #[inline]
        fn size_hint(&self) -> (uint, Option<uint>)
        {
            self.iter.size_hint()
        }
    )
);

pub struct Nodes<'a, N: 'a> {
    iter: Keys<'a, N, Vec<N>>
}

impl<'a, N: 'a> Iterator<&'a N> for Nodes<'a, N>
{
    iterator_methods!(&'a N);
}

pub struct Neighbors<'a, N: 'a> {
    iter: Map<&'a N, N, Items<'a, N>, fn(&N) -> N>,
}

impl<'a, N> Iterator<N> for Neighbors<'a, N>
{
    iterator_methods!(N);
}

pub struct Edges<'a, N: 'a + Copy + PartialOrd + Eq + Hash, E: 'a> {
    pub from: N,
    pub edges: &'a HashMap<(N, N), E>,
    pub iter: Neighbors<'a, N>,
}

impl<'a, N, E> Iterator<(N, &'a E)> for Edges<'a, N, E>
    where N: 'a + Copy + PartialOrd + Eq + Hash, E: 'a
{
    fn next(&mut self) -> Option<(N, &'a E)>
    {
        match self.iter.next() {
            None => None,
            Some(b) => {
                let a = self.from;
                match self.edges.get(&edge_key(a, b)) {
                    None => unreachable!(),
                    Some(edge) => {
                        Some((b, edge))
                    }
                }
            }
        }
    }
}

pub struct BFT<'a, G, N, F, Neighbors>
    where
        G: 'a,
        N: 'a + Copy + PartialOrd + Eq + Hash,
        F: FnMut(&G, N) -> Neighbors,
        Neighbors: Iterator<N>,
{
    pub graph: &'a G,
    pub stack: RingBuf<N>,
    pub visited: HashSet<N>,
    pub neighbors: F,
}

impl<'a, G, N, F, Neighbors> Iterator<N> for BFT<'a, G, N, F, Neighbors>
    where
        G: 'a,
        N: 'a + Copy + PartialOrd + Eq + Hash,
        F: FnMut(&G, N) -> Neighbors,
        Neighbors: Iterator<N>,
{
    fn next(&mut self) -> Option<N>
    {
        while let Some(node) = self.stack.pop_front() {
            if !self.visited.insert(node) {
                continue;
            }

            for succ in (self.neighbors)(self.graph, node) {
                if !self.visited.contains(&succ) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

pub struct BreadthFirstTraversal<'a, N, E>
    where N: 'a + Copy + PartialOrd + Eq + Hash, E: 'a
{
    graph: &'a Graph<N, E>,
    stack: RingBuf<N>,
    visited: HashSet<N>,
}

impl<'a, N, E> Iterator<N> for BreadthFirstTraversal<'a, N, E>
    where N: 'a + Copy + PartialOrd + Eq + Hash, E: 'a
{
    fn next(&mut self) -> Option<N>
    {
        while let Some(node) = self.stack.pop_front() {
            if !self.visited.insert(node) {
                continue;
            }

            for succ in self.graph.neighbors(node) {
                if !self.visited.contains(&succ) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

pub struct DepthFirstTraversal<'a, N, E>
    where N: 'a + Copy + PartialOrd + Eq + Hash, E: 'a
{
    graph: &'a Graph<N, E>,
    stack: Vec<N>,
    visited: HashSet<N>,
}

impl<'a, N, E> Iterator<N> for DepthFirstTraversal<'a, N, E>
    where N: 'a + Copy + PartialOrd + Eq + Hash, E: 'a
{
    fn next(&mut self) -> Option<N>
    {
        while let Some(node) = self.stack.pop() {
            if !self.visited.insert(node) {
                continue;
            }

            for succ in self.graph.neighbors(node) {
                if !self.visited.contains(&succ) {
                    self.stack.push(succ);
                }
            }

            return Some(node);
        }
        None
    }
}
<commit_msg>Update bounds of BFT<commit_after>use std::hash::{Hash};
use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::RingBuf;
use std::iter::Map;
use std::collections::hash_map::{
    Keys,
    Occupied,
    Vacant,
};
use std::slice::{
    Items,
};
use std::fmt;

/// **Graph\<N, E\>** is a regular graph, with generic node values **N** and edge weights **E**.
///
/// It uses an adjacency list representation, i.e. using *O(|V| + |E|)* space.
///
/// The node type must be suitable as a hash table key (Implementing **Eq + Hash**)
/// as well as being a simple type.
///
/// The node type must implement **PartialOrd** so that the implementation can
/// properly order the pair (**a**, **b**) for an edge connecting any two nodes **a** and **b**.
#[deriving(Clone)]
pub struct Graph<N: Eq + Hash, E> {
    nodes: HashMap<N, Vec<N>>,
    edges: HashMap<(N, N), E>,
}

impl<N: Eq + Hash + fmt::Show, E: fmt::Show> fmt::Show for Graph<N, E>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.nodes.fmt(f)
    }
}

#[inline]
fn edge_key<N: Copy + PartialOrd>(a: N, b: N) -> (N, N)
{
    if a <= b { (a, b) } else { (b, a) }
}

#[inline]
fn copy<N: Copy>(n: &N) -> N { *n }

impl<N, E> Graph<N, E> where N: Copy + PartialOrd + Eq + Hash
{
    /// Create a new **Graph**.
    pub fn new() -> Graph<N, E>
    {
        Graph {
            nodes: HashMap::new(),
            edges: HashMap::new(),
        }
    }

    /// Add node **n** to the graph.
    pub fn add_node(&mut self, n: N) -> N {
        match self.nodes.entry(n) {
            Occupied(_) => {}
            Vacant(ent) => { ent.set(Vec::new()); }
        }
        n
    }

    /// Return **true** if node **n** was removed.
    pub fn remove_node(&mut self, n: N) -> bool {
        let successors = match self.nodes.remove(&n) {
            None => return false,
            Some(sus) => sus,
        };
        for succ in successors.into_iter() {
            // remove all successor links
            self.remove_single_edge(&succ, &n);
            // Remove all edge values
            self.edges.remove(&edge_key(n, succ));
        }
        true
    }

    /// Return **true** if the node is contained in the graph.
    pub fn contains_node(&self, n: N) -> bool {
        self.nodes.contains_key(&n)
    }

    /// Add an edge connecting **a** and **b** to the graph.
    ///
    /// Return **true** if edge did not previously exist.
    pub fn add_edge(&mut self, a: N, b: N, edge: E) -> bool
    {
        // Use PartialOrd to order the edges
        match self.nodes.entry(a) {
            Occupied(ent) => { ent.into_mut().push(b); }
            Vacant(ent) => { ent.set(vec![b]); }
        }
        match self.nodes.entry(b) {
            Occupied(ent) => { ent.into_mut().push(a); }
            Vacant(ent) => { ent.set(vec![a]); }
        }
        self.edges.insert(edge_key(a, b), edge).is_none()
    }

    /// Remove successor relation from a to b
    fn remove_single_edge(&mut self, a: &N, b: &N) {
        match self.nodes.get_mut(a) {
            None => {}
            Some(sus) => {
                match sus.iter().position(|elt| elt == b) {
                    Some(index) => { sus.swap_remove(index); }
                    None => {}
                }
            }
        }
    }

    /// Remove edge from **a** to **b** from the graph.
    ///
    /// Return **None** if the edge didn't exist.
    pub fn remove_edge(&mut self, a: N, b: N) -> Option<E>
    {
        self.remove_single_edge(&a, &b);
        self.remove_single_edge(&b, &a);
        self.edges.remove(&edge_key(a, b))
    }

    /// Return **true** if the edge connecting **a** with **b** is contained in the graph.
    pub fn contains_edge(&self, a: N, b: N) -> bool {
        self.edges.contains_key(&edge_key(a, b))
    }

    /// Return an iterator over the nodes of the graph.
    ///
    /// Iterator element type is **&'a N**.
    pub fn nodes<'a>(&'a self) -> Nodes<'a, N>
    {
        Nodes{iter: self.nodes.keys()}
    }

    /// Return an iterator over the nodes that are connected with **from** by edges.
    ///
    /// If the node **from** does not exist in the graph, return an empty iterator.
    ///
    /// Iterator element type is **N**.
    pub fn neighbors<'a>(&'a self, from: N) -> Neighbors<'a, N>
    {
        Neighbors{iter:
            match self.nodes.get(&from) {
                Some(neigh) => neigh.iter(),
                None => [].iter(),
            }.map(copy)
        }
    }

    /// Return an iterator over the nodes that are connected with **from** by edges,
    /// paired with the edge weight.
    ///
    /// If the node **from** does not exist in the graph, return an empty iterator.
    ///
    /// Iterator element type is **(N, &'a E)**.
    pub fn edges<'a>(&'a self, from: N) -> Edges<'a, N, E>
    {
        Edges {
            from: from,
            iter: self.neighbors(from),
            edges: &self.edges,
        }
    }

    /// Return a reference to the edge weight connecting **a** with **b**, or
    /// **None** if the edge does not exist in the graph.
    pub fn edge<'a>(&'a self, a: N, b: N) -> Option<&'a E>
    {
        self.edges.get(&edge_key(a, b))
    }

    /// Return a mutable reference to the edge weight connecting **a** with **b**, or
    /// **None** if the edge does not exist in the graph.
    pub fn edge_mut<'a>(&'a mut self, a: N, b: N) -> Option<&'a mut E>
    {
        self.edges.get_mut(&edge_key(a, b))
    }

    pub fn traverse_breadth_first(&self, start: N) -> BreadthFirstTraversal<N, E>
    {
        BreadthFirstTraversal{
            graph: self,
            stack: {
                let mut stack = RingBuf::new();
                stack.push_back(start);
                stack
            },
            visited: HashSet::new(),
        }
    }

    pub fn traverse_depth_first(&self, start: N) -> DepthFirstTraversal<N, E>
    {
        DepthFirstTraversal{
            graph: self,
            stack: vec![start],
            visited: HashSet::new(),
        }
    }
}

macro_rules! iterator_methods(
    ($elt_type:ty) => (
        #[inline]
        fn next(&mut self) -> Option<$elt_type>
        {
            self.iter.next()
        }

        #[inline]
        fn size_hint(&self) -> (uint, Option<uint>)
        {
            self.iter.size_hint()
        }
    )
);

pub struct Nodes<'a, N: 'a> {
    iter: Keys<'a, N, Vec<N>>
}

impl<'a, N: 'a> Iterator<&'a N> for Nodes<'a, N>
{
    iterator_methods!(&'a N);
}

pub struct Neighbors<'a, N: 'a> {
    iter: Map<&'a N, N, Items<'a, N>, fn(&N) -> N>,
}

impl<'a, N> Iterator<N> for Neighbors<'a, N>
{
    iterator_methods!(N);
}

pub struct Edges<'a, N: 'a + Copy + PartialOrd + Eq + Hash, E: 'a> {
    pub from: N,
    pub edges: &'a HashMap<(N, N), E>,
    pub iter: Neighbors<'a, N>,
}

impl<'a, N, E> Iterator<(N, &'a E)> for Edges<'a, N, E>
    where N: 'a + Copy + PartialOrd + Eq + Hash, E: 'a
{
    fn next(&mut self) -> Option<(N, &'a E)>
    {
        match self.iter.next() {
            None => None,
            Some(b) => {
                let a = self.from;
                match self.edges.get(&edge_key(a, b)) {
                    None => unreachable!(),
                    Some(edge) => {
                        Some((b, edge))
                    }
                }
            }
        }
    }
}

pub struct BFT<'a, G, N, F, Neighbors>
    where
        G: 'a,
        N: 'a + Copy + Eq + Hash,
        F: FnMut(&G, N) -> Neighbors,
        Neighbors: Iterator<N>,
{
    pub graph: &'a G,
    pub stack: RingBuf<N>,
    pub visited: HashSet<N>,
    pub neighbors: F,
}

impl<'a, G, N, F, Neighbors> Iterator<N> for BFT<'a, G, N, F, Neighbors>
    where
        G: 'a,
        N: 'a + Copy + Eq + Hash,
        F: FnMut(&G, N) -> Neighbors,
        Neighbors: Iterator<N>,
{
    fn next(&mut self) -> Option<N>
    {
        while let Some(node) = self.stack.pop_front() {
            if !self.visited.insert(node) {
                continue;
            }

            for succ in (self.neighbors)(self.graph, node) {
                if !self.visited.contains(&succ) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

pub struct BreadthFirstTraversal<'a, N, E>
    where N: 'a + Copy + PartialOrd + Eq + Hash, E: 'a
{
    graph: &'a Graph<N, E>,
    stack: RingBuf<N>,
    visited: HashSet<N>,
}

impl<'a, N, E> Iterator<N> for BreadthFirstTraversal<'a, N, E>
    where N: 'a + Copy + PartialOrd + Eq + Hash, E: 'a
{
    fn next(&mut self) -> Option<N>
    {
        while let Some(node) = self.stack.pop_front() {
            if !self.visited.insert(node) {
                continue;
            }

            for succ in self.graph.neighbors(node) {
                if !self.visited.contains(&succ) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

pub struct DepthFirstTraversal<'a, N, E>
    where N: 'a + Copy + PartialOrd + Eq + Hash, E: 'a
{
    graph: &'a Graph<N, E>,
    stack: Vec<N>,
    visited: HashSet<N>,
}

impl<'a, N, E> Iterator<N> for DepthFirstTraversal<'a, N, E>
    where N: 'a + Copy + PartialOrd + Eq + Hash, E: 'a
{
    fn next(&mut self) -> Option<N>
    {
        while let Some(node) = self.stack.pop() {
            if !self.visited.insert(node) {
                continue;
            }

            for succ in self.graph.neighbors(node) {
                if !self.visited.contains(&succ) {
                    self.stack.push(succ);
                }
            }

            return Some(node);
        }
        None
    }
}
<|endoftext|>


<commit_before>use uri::Uri;
use triple::*;
use namespace::*;
use node::*;
use std::slice::Iter;
use std::collections::HashMap;
use Result;

/// Representation of an RDF graph.
#[derive(Debug)]
pub struct Graph {
  /// Base URI of the RDF graph.
  base_uri: Option<Uri>,

  /// All triples of the RDF graph.
  triples: TripleStore,

  /// All namespaces associated to the RDF graph.
  namespaces: NamespaceStore,

  /// Next unique ID that can be used for a new blank node.
  next_id: u64
}

impl Graph {
  /// Constructor for the RDF graph.
  pub fn new(base_uri: Option<&Uri>) -> Graph {
    let cloned_uri = match base_uri {
      None => None,
      Some(u) => Some(u.clone())
    };

    Graph {
      base_uri: cloned_uri,
      triples: TripleStore::new(),
      namespaces: NamespaceStore::new(),
      next_id: 0
    }
  }

  /// Returns `true` if the graph does not contain any triples.
  pub fn is_empty(&self) -> bool {
    self.triples.is_empty()
  }

  /// Returns the number of triples that are stored in the graph.
  pub fn count(&self) -> usize {
    self.triples.count()
  }

  /// Returns the base URI of the graph.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::uri::Uri;
  /// use rdf_rs::graph::Graph;
  ///
  /// let base_uri = Uri::new("http://example.org/".to_string());
  /// let graph = Graph::new(Some(&base_uri));
  ///
  /// assert_eq!(graph.base_uri(), &Some(base_uri));
  /// ```
  pub fn base_uri(&self) -> &Option<Uri> {
    &self.base_uri
  }

  /// Sets the base URI of the graph.
  ///
  /// # Example
  ///
  /// todo
  ///
  pub fn set_base_uri(&mut self, uri: &Uri) {
    self.base_uri = Some(uri.clone());
  }

  /// Returns a hashmap of namespaces and prefixes.
  pub fn namespaces(&self) -> &HashMap<String, Uri> {
    self.namespaces.namespaces()
  }

  /// Adds a new namespace with a specific prefix to the graph.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::uri::Uri;
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::namespace::Namespace;
  ///
  /// let mut graph = Graph::new(None);
  /// graph.add_namespace(&Namespace::new("example".to_string(), Uri::new("http://example.org/".to_string())));
  ///
  /// assert_eq!(graph.namespaces().len(), 1);
  /// ```
  pub fn add_namespace(&mut self, ns: &Namespace) {
    self.namespaces.add(ns);
  }

  /// todo
  pub fn get_namespace_uri_by_prefix(&self, prefix: String) -> Result<&Uri> {
    self.namespaces.get_uri_by_prefix(prefix)
  }

  /// Returns a literal node of the specified namespace.
  ///
  /// # Example
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::node::Node;
  ///
  /// let graph = Graph::new(None);
  /// let literal_node = graph.create_literal_node("literal".to_string());
  ///
  /// assert_eq!(literal_node, Node::LiteralNode {
  ///   literal: "literal".to_string(),
  ///   data_type: None,
  ///   language: None
  /// });
  /// ```
  pub fn create_literal_node(&self, literal: String) -> Node {
    Node::LiteralNode {
      literal: literal,
      data_type: None,
      language: None
    }
  }

  /// Returns a literal node with a specified data type.
  ///
  /// # Example
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::node::Node;
  /// use rdf_rs::uri::Uri;
  ///
  /// let graph = Graph::new(None);
  /// let literal_node = graph.create_literal_node_with_data_type("literal".to_string(), &Uri::new("http://example.org/show/localName".to_string()));
  ///
  /// assert_eq!(literal_node, Node::LiteralNode {
  ///   literal: "literal".to_string(),
  ///   data_type: Some(Uri::new("http://example.org/show/localName".to_string())),
  ///   language: None
  /// });
  /// ```
  pub fn create_literal_node_with_data_type(&self, literal: String, data_type: &Uri) -> Node {
    Node::LiteralNode {
      literal: literal,
      data_type: Some(data_type.clone()),
      language: None
    }
  }

  /// Returns a literal node with a specified language.
  ///
  /// # Example
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::node::Node;
  ///
  /// let graph = Graph::new(None);
  /// let literal_node = graph.create_literal_node_with_language("literal".to_string(), "en".to_string());
  ///
  /// assert_eq!(literal_node, Node::LiteralNode {
  ///   literal: "literal".to_string(),
  ///   data_type: None,
  ///   language: Some("en".to_string())
  /// });
  /// ```
  pub fn create_literal_node_with_language(&self, literal: String, language: String) -> Node {
    Node::LiteralNode {
      literal: literal,
      data_type: None,
      language: Some(language)
    }
  }

  /// Returns the next unique ID that can be used for a blank node.
  fn get_next_id(&self) -> u64 {
    self.next_id
  }

  /// Creates a blank node with a unique ID.
  ///
  /// # Example
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::node::Node;
  ///
  /// let mut graph = Graph::new(None);
  /// let blank_node = graph.create_blank_node();
  ///
  /// assert_eq!(blank_node, Node::BlankNode {
  ///   id: "auto0".to_string()
  /// });
  /// ```
  pub fn create_blank_node(&mut self) -> Node {
    let id = self.get_next_id();

    self.next_id = id + 1;

    Node::BlankNode {
      id: "auto".to_string() + &id.to_string()
    }
  }

  /// Creates a blank node with the specified ID.
  ///
  /// # Example
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::node::Node;
  ///
  /// let graph = Graph::new(None);
  /// let blank_node = graph.create_blank_node_with_id("foobar".to_string());
  ///
  /// assert_eq!(blank_node, Node::BlankNode {
  ///   id: "foobar".to_string()
  /// });
  /// ```
  pub fn create_blank_node_with_id(&self, id: String) -> Node {
    Node::BlankNode {
      id: id
    }
  }

  /// Creates a new URI node.
  ///
  /// # Example
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::node::Node;
  /// use rdf_rs::uri::Uri;
  ///
  /// let graph = Graph::new(None);
  /// let uri_node = graph.create_uri_node(&Uri::new("http://example.org/show/localName".to_string()));
  ///
  /// assert_eq!(uri_node, Node::UriNode {
  ///   uri: Uri::new("http://example.org/show/localName".to_string())
  /// });
  /// ```
  pub fn create_uri_node(&self, uri: &Uri) -> Node {
    Node::UriNode {
      uri: uri.clone()
    }
  }

  /// Adds a triple to the graph.
  ///
  /// # Example
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::uri::Uri;
  /// use rdf_rs::triple::Triple;
  ///
  /// let mut graph = Graph::new(None);
  ///
  /// let subject = graph.create_blank_node();
  /// let predicate = graph.create_uri_node(&Uri::new("http://example.org/show/localName".to_string()));
  /// let object = graph.create_blank_node();
  /// let triple = Triple::new(&subject, &predicate, &object);
  ///
  /// graph.add_triple(&triple);
  ///
  /// assert_eq!(graph.count(), 1);
  /// ```
  pub fn add_triple(&mut self, triple: &Triple) {
    self.triples.add_triple(triple);
  }

  /// Adds a vector of triples.
  ///
  /// # Example
  ///
  /// todo
  ///
  pub fn add_triples(&mut self, triples: &Vec<Triple>) {
    for triple in triples {
      self.add_triple(triple);
    }
  }

  /// Deletes the triple from the graph.
  ///
  /// # Example
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::uri::Uri;
  /// use rdf_rs::triple::Triple;
  ///
  /// let mut graph = Graph::new(None);
  ///
  /// let subject = graph.create_blank_node();
  /// let predicate = graph.create_uri_node(&Uri::new("http://example.org/show/localName".to_string()));
  /// let object = graph.create_blank_node();
  /// let triple = Triple::new(&subject, &predicate, &object);
  ///
  /// graph.add_triple(&triple);
  /// graph.remove_triple(&triple);
  ///
  /// assert_eq!(graph.count(), 0);
  /// ```
  pub fn remove_triple(&mut self, triple: &Triple) {
    self.triples.remove_triple(triple);
  }

  /// Returns all triples from the store that have the specified subject node.
  pub fn get_triples_with_subject(&self, node: &Node) -> Vec<&Triple> {
    self.triples.get_triples_with_subject(node)
  }

  /// Returns all triples from the store that have the specified predicate node.
  pub fn get_triples_with_predicate(&self, node: &Node) -> Vec<&Triple> {
    self.triples.get_triples_with_predicate(node)
  }

  /// Returns all triples from the store that have the specified object node.
  pub fn get_triples_with_object(&self, node: &Node) -> Vec<&Triple> {
    self.triples.get_triples_with_object(node)
  }

  /// Returns all triples from the triple store where the subject and object nodes match the provided nodes.
  pub fn get_triples_with_subject_and_object(&self, subject_node: &Node, object_node: &Node) -> Vec<&Triple> {
    self.triples.get_triples_with_subject_and_object(subject_node, object_node)
  }

  /// Returns all triples from the triple store where the subject and predicate nodes match the provided nodes.
  pub fn get_triples_with_subject_and_predicate(&self, subject_node: &Node, predicate_node: &Node) -> Vec<&Triple> {
    self.triples.get_triples_with_subject_and_predicate(subject_node, predicate_node)
  }

  /// Returns all triples from the triple store where the predicate and object nodes match the provided nodes.
  pub fn get_triples_with_predicate_and_object(&self, predicate_node: &Node, object_node: &Node) -> Vec<&Triple> {
    self.triples.get_triples_with_predicate_and_object(predicate_node, object_node)
  }

  /// Returns an iterator over the triples of the graph.
  pub fn triples_iter(&self) -> Iter<Triple> {
    self.triples.iter()
  }
}

#[cfg(test)]
mod tests {
  use graph::Graph;
  use node::*;

  #[test]
  fn empty_graph() {
    let graph = Graph::new(None);
    assert_eq!(graph.is_empty(), true);
  }

  #[test]
  fn create_literal_node() {
    let graph = Graph::new(None);
    let literal_node = graph.create_literal_node("literal".to_string());

    assert_eq!(literal_node, Node::LiteralNode {
      literal: "literal".to_string(),
      data_type: None,
      language: None
    });
  }

  #[test]
  fn create_multiple_blank_nodes() {
    let mut graph = Graph::new(None);

    let blank_node_0 = graph.create_blank_node();
    let blank_node_1 = graph.create_blank_node();

    assert_eq!(blank_node_0, Node::BlankNode {
      id: "auto0".to_string()
    });

    assert_eq!(blank_node_1, Node::BlankNode {
      id: "auto1".to_string()
    });
  }
}<commit_msg>Add missing documentation and usage examples<commit_after>use uri::Uri;
use triple::*;
use namespace::*;
use node::*;
use std::slice::Iter;
use std::collections::HashMap;
use Result;

/// Representation of an RDF graph.
#[derive(Debug)]
pub struct Graph {
  /// Base URI of the RDF graph.
  base_uri: Option<Uri>,

  /// All triples of the RDF graph.
  triples: TripleStore,

  /// All namespaces associated to the RDF graph.
  namespaces: NamespaceStore,

  /// Next unique ID that can be used for a new blank node.
  next_id: u64
}

impl Graph {
  /// Constructor for the RDF graph.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::graph::Graph;
  ///
  /// let graph = Graph::new(None);
  /// ```
  pub fn new(base_uri: Option<&Uri>) -> Graph {
    let cloned_uri = match base_uri {
      None => None,
      Some(u) => Some(u.clone())
    };

    Graph {
      base_uri: cloned_uri,
      triples: TripleStore::new(),
      namespaces: NamespaceStore::new(),
      next_id: 0
    }
  }

  /// Returns `true` if the graph does not contain any triples.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::graph::Graph;
  ///
  /// let graph = Graph::new(None);
  ///
  /// assert_eq!(graph.is_empty(), true);
  /// ```
  pub fn is_empty(&self) -> bool {
    self.triples.is_empty()
  }

  /// Returns the number of triples that are stored in the graph.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::graph::Graph;
  ///
  /// let graph = Graph::new(None);
  ///
  /// assert_eq!(graph.count(), 0);
  /// ```
  pub fn count(&self) -> usize {
    self.triples.count()
  }

  /// Returns the base URI of the graph.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::uri::Uri;
  /// use rdf_rs::graph::Graph;
  ///
  /// let base_uri = Uri::new("http://example.org/".to_string());
  /// let graph = Graph::new(Some(&base_uri));
  ///
  /// assert_eq!(graph.base_uri(), &Some(base_uri));
  /// ```
  pub fn base_uri(&self) -> &Option<Uri> {
    &self.base_uri
  }

  /// Sets the base URI of the graph.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::uri::Uri;
  /// use rdf_rs::graph::Graph;
  ///
  /// let base_uri = Uri::new("http://base.example.org/".to_string());
  /// let mut graph = Graph::new(None);
  ///
  /// graph.set_base_uri(&base_uri);
  ///
  /// assert_eq!(graph.base_uri(), &Some(base_uri));
  /// ```
  pub fn set_base_uri(&mut self, uri: &Uri) {
    self.base_uri = Some(uri.clone());
  }

  /// Returns a hash map of namespaces and prefixes.
  pub fn namespaces(&self) -> &HashMap<String, Uri> {
    self.namespaces.namespaces()
  }

  /// Adds a new namespace with a specific prefix to the graph.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::uri::Uri;
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::namespace::Namespace;
  ///
  /// let mut graph = Graph::new(None);
  /// graph.add_namespace(&Namespace::new("example".to_string(), Uri::new("http://example.org/".to_string())));
  ///
  /// assert_eq!(graph.namespaces().len(), 1);
  /// ```
  pub fn add_namespace(&mut self, ns: &Namespace) {
    self.namespaces.add(ns);
  }

  /// Returns the URI of a namespace with the provided prefix.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::uri::Uri;
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::namespace::Namespace;
  ///
  /// let mut graph = Graph::new(None);
  /// let uri = Uri::new("http://example.org/".to_string());
  /// graph.add_namespace(&Namespace::new("example".to_string(), uri.to_owned()));
  ///
  /// assert_eq!(graph.get_namespace_uri_by_prefix("example".to_string()).unwrap(), &uri);
  /// ```
  pub fn get_namespace_uri_by_prefix(&self, prefix: String) -> Result<&Uri> {
    self.namespaces.get_uri_by_prefix(prefix)
  }

  /// Returns a literal node of the specified namespace.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::node::Node;
  ///
  /// let graph = Graph::new(None);
  /// let literal_node = graph.create_literal_node("literal".to_string());
  ///
  /// assert_eq!(literal_node, Node::LiteralNode {
  ///   literal: "literal".to_string(),
  ///   data_type: None,
  ///   language: None
  /// });
  /// ```
  pub fn create_literal_node(&self, literal: String) -> Node {
    Node::LiteralNode {
      literal: literal,
      data_type: None,
      language: None
    }
  }

  /// Returns a literal node with a specified data type.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::node::Node;
  /// use rdf_rs::uri::Uri;
  ///
  /// let graph = Graph::new(None);
  /// let literal_node = graph.create_literal_node_with_data_type("literal".to_string(), &Uri::new("http://example.org/show/localName".to_string()));
  ///
  /// assert_eq!(literal_node, Node::LiteralNode {
  ///   literal: "literal".to_string(),
  ///   data_type: Some(Uri::new("http://example.org/show/localName".to_string())),
  ///   language: None
  /// });
  /// ```
  pub fn create_literal_node_with_data_type(&self, literal: String, data_type: &Uri) -> Node {
    Node::LiteralNode {
      literal: literal,
      data_type: Some(data_type.clone()),
      language: None
    }
  }

  /// Returns a literal node with a specified language.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::node::Node;
  ///
  /// let graph = Graph::new(None);
  /// let literal_node = graph.create_literal_node_with_language("literal".to_string(), "en".to_string());
  ///
  /// assert_eq!(literal_node, Node::LiteralNode {
  ///   literal: "literal".to_string(),
  ///   data_type: None,
  ///   language: Some("en".to_string())
  /// });
  /// ```
  pub fn create_literal_node_with_language(&self, literal: String, language: String) -> Node {
    Node::LiteralNode {
      literal: literal,
      data_type: None,
      language: Some(language)
    }
  }

  /// Returns the next unique ID that can be used for a blank node.
  fn get_next_id(&self) -> u64 {
    self.next_id
  }

  /// Creates a blank node with a unique ID.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::node::Node;
  ///
  /// let mut graph = Graph::new(None);
  /// let blank_node = graph.create_blank_node();
  ///
  /// assert_eq!(blank_node, Node::BlankNode {
  ///   id: "auto0".to_string()
  /// });
  /// ```
  pub fn create_blank_node(&mut self) -> Node {
    let id = self.get_next_id();

    self.next_id = id + 1;

    Node::BlankNode {
      id: "auto".to_string() + &id.to_string()
    }
  }

  /// Creates a blank node with the specified ID.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::node::Node;
  ///
  /// let graph = Graph::new(None);
  /// let blank_node = graph.create_blank_node_with_id("foobar".to_string());
  ///
  /// assert_eq!(blank_node, Node::BlankNode {
  ///   id: "foobar".to_string()
  /// });
  /// ```
  pub fn create_blank_node_with_id(&self, id: String) -> Node {
    Node::BlankNode {
      id: id
    }
  }

  /// Creates a new URI node.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::node::Node;
  /// use rdf_rs::uri::Uri;
  ///
  /// let graph = Graph::new(None);
  /// let uri_node = graph.create_uri_node(&Uri::new("http://example.org/show/localName".to_string()));
  ///
  /// assert_eq!(uri_node, Node::UriNode {
  ///   uri: Uri::new("http://example.org/show/localName".to_string())
  /// });
  /// ```
  pub fn create_uri_node(&self, uri: &Uri) -> Node {
    Node::UriNode {
      uri: uri.clone()
    }
  }

  /// Adds a triple to the graph.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::uri::Uri;
  /// use rdf_rs::triple::Triple;
  ///
  /// let mut graph = Graph::new(None);
  ///
  /// let subject = graph.create_blank_node();
  /// let predicate = graph.create_uri_node(&Uri::new("http://example.org/show/localName".to_string()));
  /// let object = graph.create_blank_node();
  /// let triple = Triple::new(&subject, &predicate, &object);
  ///
  /// graph.add_triple(&triple);
  ///
  /// assert_eq!(graph.count(), 1);
  /// ```
  pub fn add_triple(&mut self, triple: &Triple) {
    self.triples.add_triple(triple);
  }

  /// Adds a vector of triples.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::uri::Uri;
  /// use rdf_rs::triple::Triple;
  ///
  /// let mut graph = Graph::new(None);
  ///
  /// let subject = graph.create_blank_node();
  /// let predicate = graph.create_uri_node(&Uri::new("http://example.org/show/localName".to_string()));
  /// let object = graph.create_blank_node();
  ///
  /// let triple1 = Triple::new(&subject, &predicate, &object);
  /// let triple2 = Triple::new(&subject, &predicate, &object);
  ///
  /// graph.add_triples(&vec![triple1, triple2]);
  ///
  /// assert_eq!(graph.count(), 2);
  /// ```
  pub fn add_triples(&mut self, triples: &Vec<Triple>) {
    for triple in triples {
      self.add_triple(triple);
    }
  }

  /// Deletes the triple from the graph.
  ///
  /// # Example
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::uri::Uri;
  /// use rdf_rs::triple::Triple;
  ///
  /// let mut graph = Graph::new(None);
  ///
  /// let subject = graph.create_blank_node();
  /// let predicate = graph.create_uri_node(&Uri::new("http://example.org/show/localName".to_string()));
  /// let object = graph.create_blank_node();
  /// let triple = Triple::new(&subject, &predicate, &object);
  ///
  /// graph.add_triple(&triple);
  /// graph.remove_triple(&triple);
  ///
  /// assert_eq!(graph.count(), 0);
  /// ```
  pub fn remove_triple(&mut self, triple: &Triple) {
    self.triples.remove_triple(triple);
  }

  /// Returns all triples from the store that have the specified subject node.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::uri::Uri;
  /// use rdf_rs::triple::Triple;
  ///
  /// let mut graph = Graph::new(None);
  ///
  /// let subject1 = graph.create_blank_node();
  /// let subject2 = graph.create_blank_node();
  /// let predicate = graph.create_uri_node(&Uri::new("http://example.org/show/localName".to_string()));
  /// let object = graph.create_blank_node();
  ///
  /// let triple1 = Triple::new(&subject1, &predicate, &object);
  /// let triple2 = Triple::new(&subject2, &predicate, &object);
  ///
  /// graph.add_triples(&vec![triple1.to_owned(), triple2]);
  ///
  /// assert_eq!(graph.get_triples_with_subject(&subject1), vec![&triple1]);
  /// ```
  pub fn get_triples_with_subject(&self, node: &Node) -> Vec<&Triple> {
    self.triples.get_triples_with_subject(node)
  }

  /// Returns all triples from the store that have the specified predicate node.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::uri::Uri;
  /// use rdf_rs::triple::Triple;
  ///
  /// let mut graph = Graph::new(None);
  ///
  /// let subject1 = graph.create_blank_node();
  /// let subject2 = graph.create_blank_node();
  /// let predicate = graph.create_uri_node(&Uri::new("http://example.org/show/localName".to_string()));
  /// let object = graph.create_blank_node();
  ///
  /// let triple1 = Triple::new(&subject1, &predicate, &object);
  /// let triple2 = Triple::new(&subject2, &predicate, &object);
  ///
  /// graph.add_triples(&vec![triple1.to_owned(), triple2.to_owned()]);
  ///
  /// assert_eq!(graph.get_triples_with_predicate(&predicate), vec![&triple1, &triple2]);
  /// ```
  pub fn get_triples_with_predicate(&self, node: &Node) -> Vec<&Triple> {
    self.triples.get_triples_with_predicate(node)
  }

  /// Returns all triples from the store that have the specified object node.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::uri::Uri;
  /// use rdf_rs::triple::Triple;
  ///
  /// let mut graph = Graph::new(None);
  ///
  /// let subject1 = graph.create_blank_node();
  /// let subject2 = graph.create_blank_node();
  /// let predicate = graph.create_uri_node(&Uri::new("http://example.org/show/localName".to_string()));
  /// let object = graph.create_blank_node();
  ///
  /// let triple1 = Triple::new(&subject1, &predicate, &object);
  /// let triple2 = Triple::new(&subject2, &predicate, &object);
  ///
  /// graph.add_triples(&vec![triple1.to_owned(), triple2.to_owned()]);
  ///
  /// assert_eq!(graph.get_triples_with_object(&object), vec![&triple1, &triple2]);
  /// ```
  pub fn get_triples_with_object(&self, node: &Node) -> Vec<&Triple> {
    self.triples.get_triples_with_object(node)
  }

  /// Returns all triples from the triple store where the subject and object nodes match the provided nodes.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::uri::Uri;
  /// use rdf_rs::triple::Triple;
  ///
  /// let mut graph = Graph::new(None);
  ///
  /// let subject1 = graph.create_blank_node();
  /// let subject2 = graph.create_blank_node();
  /// let predicate = graph.create_uri_node(&Uri::new("http://example.org/show/localName".to_string()));
  /// let object = graph.create_blank_node();
  ///
  /// let triple1 = Triple::new(&subject1, &predicate, &object);
  /// let triple2 = Triple::new(&subject2, &predicate, &object);
  ///
  /// graph.add_triples(&vec![triple1.to_owned(), triple2]);
  ///
  /// assert_eq!(graph.get_triples_with_subject_and_object(&subject1, &object), vec![&triple1]);
  /// ```
  pub fn get_triples_with_subject_and_object(&self, subject_node: &Node, object_node: &Node) -> Vec<&Triple> {
    self.triples.get_triples_with_subject_and_object(subject_node, object_node)
  }

  /// Returns all triples from the triple store where the subject and predicate nodes match the provided nodes.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::uri::Uri;
  /// use rdf_rs::triple::Triple;
  ///
  /// let mut graph = Graph::new(None);
  ///
  /// let subject1 = graph.create_blank_node();
  /// let subject2 = graph.create_blank_node();
  /// let predicate = graph.create_uri_node(&Uri::new("http://example.org/show/localName".to_string()));
  /// let object = graph.create_blank_node();
  ///
  /// let triple1 = Triple::new(&subject1, &predicate, &object);
  /// let triple2 = Triple::new(&subject2, &predicate, &object);
  ///
  /// graph.add_triples(&vec![triple1.to_owned(), triple2]);
  ///
  /// assert_eq!(graph.get_triples_with_subject_and_predicate(&subject1, &predicate), vec![&triple1]);
  /// ```
  pub fn get_triples_with_subject_and_predicate(&self, subject_node: &Node, predicate_node: &Node) -> Vec<&Triple> {
    self.triples.get_triples_with_subject_and_predicate(subject_node, predicate_node)
  }

  /// Returns all triples from the triple store where the predicate and object nodes match the provided nodes.
  ///
  /// # Example
  ///
  /// ```
  /// use rdf_rs::graph::Graph;
  /// use rdf_rs::uri::Uri;
  /// use rdf_rs::triple::Triple;
  ///
  /// let mut graph = Graph::new(None);
  ///
  /// let subject1 = graph.create_blank_node();
  /// let subject2 = graph.create_blank_node();
  /// let predicate = graph.create_uri_node(&Uri::new("http://example.org/show/localName".to_string()));
  /// let object = graph.create_blank_node();
  ///
  /// let triple1 = Triple::new(&subject1, &predicate, &object);
  /// let triple2 = Triple::new(&subject2, &predicate, &object);
  ///
  /// graph.add_triples(&vec![triple1.to_owned(), triple2.to_owned()]);
  ///
  /// assert_eq!(graph.get_triples_with_predicate_and_object(&predicate, &object), vec![&triple1, &triple2]);
  /// ```
  pub fn get_triples_with_predicate_and_object(&self, predicate_node: &Node, object_node: &Node) -> Vec<&Triple> {
    self.triples.get_triples_with_predicate_and_object(predicate_node, object_node)
  }

  /// Returns an iterator over the triples of the graph.
  pub fn triples_iter(&self) -> Iter<Triple> {
    self.triples.iter()
  }
}

#[cfg(test)]
mod tests {
  use graph::Graph;
  use node::*;

  #[test]
  fn empty_graph() {
    let graph = Graph::new(None);
    assert_eq!(graph.is_empty(), true);
  }

  #[test]
  fn create_literal_node() {
    let graph = Graph::new(None);
    let literal_node = graph.create_literal_node("literal".to_string());

    assert_eq!(literal_node, Node::LiteralNode {
      literal: "literal".to_string(),
      data_type: None,
      language: None
    });
  }

  #[test]
  fn create_multiple_blank_nodes() {
    let mut graph = Graph::new(None);

    let blank_node_0 = graph.create_blank_node();
    let blank_node_1 = graph.create_blank_node();

    assert_eq!(blank_node_0, Node::BlankNode {
      id: "auto0".to_string()
    });

    assert_eq!(blank_node_1, Node::BlankNode {
      id: "auto1".to_string()
    });
  }
}<|endoftext|>