<commit_before>use crate::fmt;
use crate::io::{self, IoVec, IoVecMut};
use crate::net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr};
use crate::time::Duration;
use crate::sys::{unsupported, Void};
use crate::convert::TryFrom;

pub struct TcpStream(Void);

impl TcpStream {
    pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
        unsupported()
    }

    pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
        unsupported()
    }

    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn read_vectored(&self, _: &mut [IoVecMut<'_>]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn write(&self, _: &[u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn write_vectored(&self, _: &[IoVec<'_>]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
        match self.0 {}
    }

    pub fn duplicate(&self) -> io::Result<TcpStream> {
        match self.0 {}
    }

    pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn nodelay(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn ttl(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        match self.0 {}
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }
}

impl fmt::Debug for TcpStream {
    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {}
    }
}

pub struct TcpListener(Void);

impl TcpListener {
    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
        unsupported()
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
        match self.0 {}
    }

    pub fn duplicate(&self) -> io::Result<TcpListener> {
        match self.0 {}
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn ttl(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn only_v6(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        match self.0 {}
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }
}

impl fmt::Debug for TcpListener {
    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {}
    }
}

pub struct UdpSocket(Void);

impl UdpSocket {
    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
        unsupported()
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
        match self.0 {}
    }

    pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
        match self.0 {}
    }

    pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn duplicate(&self) -> io::Result<UdpSocket> {
        match self.0 {}
    }

    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn broadcast(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
                         -> io::Result<()> {
        match self.0 {}
    }

    pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32)
                         -> io::Result<()> {
        match self.0 {}
    }

    pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
                          -> io::Result<()> {
        match self.0 {}
    }

    pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32)
                          -> io::Result<()> {
        match self.0 {}
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn ttl(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        match self.0 {}
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn send(&self, _: &[u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
        match self.0 {}
    }
}

impl fmt::Debug for UdpSocket {
    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {}
    }
}

pub struct LookupHost(Void);

impl LookupHost {
    pub fn port(&self) -> u16 {
        match self.0 {}
    }
}

impl Iterator for LookupHost {
    type Item = SocketAddr;
    fn next(&mut self) -> Option<SocketAddr> {
        match self.0 {}
    }
}

impl TryFrom<&str> for LookupHost {
    type Error = io::Error;

    fn try_from(_v: &str) -> io::Result<LookupHost> {
        unsupported()
    }
}

impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
    type Error = io::Error;

    fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
        unsupported()
    }
}

#[allow(nonstandard_style)]
pub mod netc {
    pub const AF_INET: u8 = 0;
    pub const AF_INET6: u8 = 1;
    pub type sa_family_t = u8;

    #[derive(Copy, Clone)]
    pub struct in_addr {
        pub s_addr: u32,
    }

    #[derive(Copy, Clone)]
    pub struct sockaddr_in {
        pub sin_family: sa_family_t,
        pub sin_port: u16,
        pub sin_addr: in_addr,
    }

    #[derive(Copy, Clone)]
    pub struct in6_addr {
        pub s6_addr: [u8; 16],
    }

    #[derive(Copy, Clone)]
    pub struct sockaddr_in6 {
        pub sin6_family: sa_family_t,
        pub sin6_port: u16,
        pub sin6_addr: in6_addr,
        pub sin6_flowinfo: u32,
        pub sin6_scope_id: u32,
    }

    #[derive(Copy, Clone)]
    pub struct sockaddr {
    }

    pub type socklen_t = usize;
}
<commit_msg>Add UdpSocket peer_addr implementation for Wasm<commit_after>use crate::fmt;
use crate::io::{self, IoVec, IoVecMut};
use crate::net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr};
use crate::time::Duration;
use crate::sys::{unsupported, Void};
use crate::convert::TryFrom;

pub struct TcpStream(Void);

impl TcpStream {
    pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
        unsupported()
    }

    pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
        unsupported()
    }

    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn read_vectored(&self, _: &mut [IoVecMut<'_>]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn write(&self, _: &[u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn write_vectored(&self, _: &[IoVec<'_>]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
        match self.0 {}
    }

    pub fn duplicate(&self) -> io::Result<TcpStream> {
        match self.0 {}
    }

    pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn nodelay(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn ttl(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        match self.0 {}
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }
}

impl fmt::Debug for TcpStream {
    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {}
    }
}

pub struct TcpListener(Void);

impl TcpListener {
    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
        unsupported()
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
        match self.0 {}
    }

    pub fn duplicate(&self) -> io::Result<TcpListener> {
        match self.0 {}
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn ttl(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn only_v6(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        match self.0 {}
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }
}

impl fmt::Debug for TcpListener {
    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {}
    }
}

pub struct UdpSocket(Void);

impl UdpSocket {
    pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
        unsupported()
    }

    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
        match self.0 {}
    }

    pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
        match self.0 {}
    }

    pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
        match self.0 {}
    }

    pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn duplicate(&self) -> io::Result<UdpSocket> {
        match self.0 {}
    }

    pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
        match self.0 {}
    }

    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
        match self.0 {}
    }

    pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn broadcast(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
        match self.0 {}
    }

    pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
                         -> io::Result<()> {
        match self.0 {}
    }

    pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32)
                         -> io::Result<()> {
        match self.0 {}
    }

    pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
                          -> io::Result<()> {
        match self.0 {}
    }

    pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32)
                          -> io::Result<()> {
        match self.0 {}
    }

    pub fn set_ttl(&self, _: u32) -> io::Result<()> {
        match self.0 {}
    }

    pub fn ttl(&self) -> io::Result<u32> {
        match self.0 {}
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        match self.0 {}
    }

    pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
        match self.0 {}
    }

    pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn send(&self, _: &[u8]) -> io::Result<usize> {
        match self.0 {}
    }

    pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
        match self.0 {}
    }
}

impl fmt::Debug for UdpSocket {
    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {}
    }
}

pub struct LookupHost(Void);

impl LookupHost {
    pub fn port(&self) -> u16 {
        match self.0 {}
    }
}

impl Iterator for LookupHost {
    type Item = SocketAddr;
    fn next(&mut self) -> Option<SocketAddr> {
        match self.0 {}
    }
}

impl TryFrom<&str> for LookupHost {
    type Error = io::Error;

    fn try_from(_v: &str) -> io::Result<LookupHost> {
        unsupported()
    }
}

impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
    type Error = io::Error;

    fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
        unsupported()
    }
}

#[allow(nonstandard_style)]
pub mod netc {
    pub const AF_INET: u8 = 0;
    pub const AF_INET6: u8 = 1;
    pub type sa_family_t = u8;

    #[derive(Copy, Clone)]
    pub struct in_addr {
        pub s_addr: u32,
    }

    #[derive(Copy, Clone)]
    pub struct sockaddr_in {
        pub sin_family: sa_family_t,
        pub sin_port: u16,
        pub sin_addr: in_addr,
    }

    #[derive(Copy, Clone)]
    pub struct in6_addr {
        pub s6_addr: [u8; 16],
    }

    #[derive(Copy, Clone)]
    pub struct sockaddr_in6 {
        pub sin6_family: sa_family_t,
        pub sin6_port: u16,
        pub sin6_addr: in6_addr,
        pub sin6_flowinfo: u32,
        pub sin6_scope_id: u32,
    }

    #[derive(Copy, Clone)]
    pub struct sockaddr {
    }

    pub type socklen_t = usize;
}
<|endoftext|>


<commit_before>use std::path::Path;

use anyhow::Result;

use sorted_iter::{
    assume::*,
    SortedPairIterator,
};

use itertools::Itertools;

pub mod ds;
pub mod utils;

use crate::normalize::ds::so_tree;
use rnc_core::psql::JsonlIterator;

pub fn write_merge(
    base_file: &Path,
    crs_file: &Path,
    feedback_file: &Path,
    go_annotations_file: &Path,
    interacting_proteins_file: &Path,
    interacting_rnas_file: &Path,
    precompute_file: &Path,
    qa_status_file: &Path,
    r2dt_hits_file: &Path,
    rfam_hits_file: &Path,
    so_term_tree_file: &Path,
    output_file: &Path,
) -> Result<()> {
    let so_info = so_tree::load(&so_term_tree_file)?;
    let mut writer = rnc_utils::buf_writer(output_file)?;

    let base = JsonlIterator::from_path(base_file)?;
    let base = base.map(|b: ds::basic::Basic| (b.id, b));
    let base = base.into_iter().assume_sorted_by_key();

    let crs = JsonlIterator::from_path(crs_file)?;
    let crs = crs.group_by(|c: &ds::crs::Crs| c.id);
    let crs = crs.into_iter().assume_sorted_by_key();

    let feedback = JsonlIterator::from_path(feedback_file)?;
    let feedback = feedback.group_by(|f: &ds::feedback::Feedback| f.id);
    let feedback = feedback.into_iter().assume_sorted_by_key();

    let go_annotations = JsonlIterator::from_path(go_annotations_file)?;
    let go_annotations = go_annotations.group_by(|f: &ds::go_annotation::GoAnnotation| f.id);
    let go_annotations = go_annotations.into_iter().assume_sorted_by_key();

    let interacting_proteins = JsonlIterator::from_path(interacting_proteins_file)?;
    let interacting_proteins =
        interacting_proteins.group_by(|i: &ds::interacting_protein::InteractingProtein| i.id);
    let interacting_proteins = interacting_proteins.into_iter().assume_sorted_by_key();

    let interacting_rnas = JsonlIterator::from_path(interacting_rnas_file)?;
    let interacting_rnas =
        interacting_rnas.group_by(|i: &ds::interacting_rna::InteractingRna| i.id);
    let interacting_rnas = interacting_rnas.into_iter().assume_sorted_by_key();

    let precompute = JsonlIterator::from_path(precompute_file)?;
    let precompute = precompute.map(|p: ds::precompute::Precompute| (p.id, p));
    let precompute = precompute.into_iter().assume_sorted_by_key();

    let qa_status = JsonlIterator::from_path(qa_status_file)?;
    let qa_status = qa_status.map(|q: ds::qa_status::QaStatus| (q.id, q));
    let qa_status = qa_status.into_iter().assume_sorted_by_key();

    let r2dt_hits = JsonlIterator::from_path(r2dt_hits_file)?;
    let r2dt_hits = r2dt_hits.map(|h: ds::r2dt::R2dt| (h.id, h));
    let r2dt_hits = r2dt_hits.into_iter().assume_sorted_by_key();

    let rfam_hits = JsonlIterator::from_path(rfam_hits_file)?;
    let rfam_hits = rfam_hits.group_by(|i: &ds::rfam_hit::RfamHit| i.id);
    let rfam_hits = rfam_hits.into_iter().assume_sorted_by_key();

    let merged = base
        .join(precompute)
        .join(qa_status)
        .left_join(crs)
        .left_join(feedback)
        .left_join(go_annotations)
        .left_join(interacting_proteins)
        .left_join(interacting_rnas)
        .left_join(r2dt_hits)
        .left_join(rfam_hits);

    for (id, entry) in merged {
        let (
            (
                (
                    (
                        (((((basic, precompute), qa_status), crs), feedback), go_annotations),
                        interacting_proteins,
                    ),
                    interacting_rnas,
                ),
                r2dt_hits,
            ),
            rfam_hits,
        ) = entry;

        let so_rna_type_tree = so_info[precompute.so_rna_type()].clone();

        let raw = ds::entry::Raw {
            id,
            base: basic,
            precompute,
            qa_status,
            crs: crs.into_iter().map(|g| g.into_iter()).flatten().collect(),
            feedback: feedback.into_iter().map(|g| g.into_iter()).flatten().collect(),
            go_annotations: go_annotations.into_iter().map(|g| g.into_iter()).flatten().collect(),
            interacting_proteins: interacting_proteins
                .into_iter()
                .map(|g| g.into_iter())
                .flatten()
                .collect(),
            interacting_rnas: interacting_rnas
                .into_iter()
                .map(|g| g.into_iter())
                .flatten()
                .collect(),
            r2dt: r2dt_hits,
            rfam_hits: rfam_hits.into_iter().map(|g| g.into_iter()).flatten().collect(),
            so_tree: so_rna_type_tree,
        };

        serde_json::to_writer(&mut writer, &raw)?;
        writeln!(&mut writer)?;
    }

    Ok(())
}

pub fn write(accession_file: &Path, metadata_file: &Path, output_file: &Path) -> Result<()> {
    let mut writer = rnc_utils::buf_writer(output_file)?;

    let metadata = JsonlIterator::from_path(metadata_file)?;
    let metadata = metadata.map(|r: ds::entry::Raw| (r.id, r));
    let metadata = metadata.into_iter().assume_sorted_by_key();

    let accessions = JsonlIterator::from_path(accession_file)?;
    let accessions = accessions.group_by(|a: &ds::accession::RawAccession| a.id);
    let accessions = accessions.into_iter().assume_sorted_by_key();

    let merged = accessions.join(metadata);

    for (_id, entry) in merged {
        let (accessions, metadata) = entry;
        let normalized = ds::entry::Normalized::new(metadata, accessions.collect())?;
        serde_json::to_writer(&mut writer, &normalized)?;
        writeln!(&mut writer)?;
    }

    Ok(())
}
<commit_msg>Add sanity to check to ensure all data is merged<commit_after>use std::path::Path;

use anyhow::{
    anyhow,
    Result,
};

use sorted_iter::{
    assume::*,
    SortedPairIterator,
};

use itertools::Itertools;

pub mod ds;
pub mod utils;

use crate::normalize::ds::so_tree;
use rnc_core::psql::JsonlIterator;

pub fn write_merge(
    base_file: &Path,
    crs_file: &Path,
    feedback_file: &Path,
    go_annotations_file: &Path,
    interacting_proteins_file: &Path,
    interacting_rnas_file: &Path,
    precompute_file: &Path,
    qa_status_file: &Path,
    r2dt_hits_file: &Path,
    rfam_hits_file: &Path,
    so_term_tree_file: &Path,
    output_file: &Path,
) -> Result<()> {
    let so_info = so_tree::load(&so_term_tree_file)?;
    let mut writer = rnc_utils::buf_writer(output_file)?;

    let base = JsonlIterator::from_path(base_file)?;
    let base = base.map(|b: ds::basic::Basic| (b.id, b));
    let base = base.into_iter().assume_sorted_by_key();

    let crs = JsonlIterator::from_path(crs_file)?;
    let crs = crs.group_by(|c: &ds::crs::Crs| c.id);
    let crs = crs.into_iter().assume_sorted_by_key();

    let feedback = JsonlIterator::from_path(feedback_file)?;
    let feedback = feedback.group_by(|f: &ds::feedback::Feedback| f.id);
    let feedback = feedback.into_iter().assume_sorted_by_key();

    let go_annotations = JsonlIterator::from_path(go_annotations_file)?;
    let go_annotations = go_annotations.group_by(|f: &ds::go_annotation::GoAnnotation| f.id);
    let go_annotations = go_annotations.into_iter().assume_sorted_by_key();

    let interacting_proteins = JsonlIterator::from_path(interacting_proteins_file)?;
    let interacting_proteins =
        interacting_proteins.group_by(|i: &ds::interacting_protein::InteractingProtein| i.id);
    let interacting_proteins = interacting_proteins.into_iter().assume_sorted_by_key();

    let interacting_rnas = JsonlIterator::from_path(interacting_rnas_file)?;
    let interacting_rnas =
        interacting_rnas.group_by(|i: &ds::interacting_rna::InteractingRna| i.id);
    let interacting_rnas = interacting_rnas.into_iter().assume_sorted_by_key();

    let precompute = JsonlIterator::from_path(precompute_file)?;
    let precompute = precompute.map(|p: ds::precompute::Precompute| (p.id, p));
    let precompute = precompute.into_iter().assume_sorted_by_key();

    let qa_status = JsonlIterator::from_path(qa_status_file)?;
    let qa_status = qa_status.map(|q: ds::qa_status::QaStatus| (q.id, q));
    let qa_status = qa_status.into_iter().assume_sorted_by_key();

    let r2dt_hits = JsonlIterator::from_path(r2dt_hits_file)?;
    let r2dt_hits = r2dt_hits.map(|h: ds::r2dt::R2dt| (h.id, h));
    let r2dt_hits = r2dt_hits.into_iter().assume_sorted_by_key();

    let rfam_hits = JsonlIterator::from_path(rfam_hits_file)?;
    let rfam_hits = rfam_hits.group_by(|i: &ds::rfam_hit::RfamHit| i.id);
    let rfam_hits = rfam_hits.into_iter().assume_sorted_by_key();

    let merged = base
        .join(precompute)
        .join(qa_status)
        .left_join(crs)
        .left_join(feedback)
        .left_join(go_annotations)
        .left_join(interacting_proteins)
        .left_join(interacting_rnas)
        .left_join(r2dt_hits)
        .left_join(rfam_hits);

    for (id, entry) in merged {
        let (
            (
                (
                    (
                        (((((basic, precompute), qa_status), crs), feedback), go_annotations),
                        interacting_proteins,
                    ),
                    interacting_rnas,
                ),
                r2dt_hits,
            ),
            rfam_hits,
        ) = entry;

        let so_rna_type_tree = so_info[precompute.so_rna_type()].clone();

        let raw = ds::entry::Raw {
            id,
            base: basic,
            precompute,
            qa_status,
            crs: crs.into_iter().map(|g| g.into_iter()).flatten().collect(),
            feedback: feedback.into_iter().map(|g| g.into_iter()).flatten().collect(),
            go_annotations: go_annotations.into_iter().map(|g| g.into_iter()).flatten().collect(),
            interacting_proteins: interacting_proteins
                .into_iter()
                .map(|g| g.into_iter())
                .flatten()
                .collect(),
            interacting_rnas: interacting_rnas
                .into_iter()
                .map(|g| g.into_iter())
                .flatten()
                .collect(),
            r2dt: r2dt_hits,
            rfam_hits: rfam_hits.into_iter().map(|g| g.into_iter()).flatten().collect(),
            so_tree: so_rna_type_tree,
        };

        serde_json::to_writer(&mut writer, &raw)?;
        writeln!(&mut writer)?;
    }

    Ok(())
}

pub fn write(accession_file: &Path, metadata_file: &Path, output_file: &Path) -> Result<()> {
    let mut writer = rnc_utils::buf_writer(output_file)?;

    let metadata = JsonlIterator::from_path(metadata_file)?;
    let metadata = metadata.map(|r: ds::entry::Raw| (r.id, r));
    let metadata = metadata.into_iter().assume_sorted_by_key();

    let accessions = JsonlIterator::from_path(accession_file)?;
    let accessions = accessions.group_by(|a: &ds::accession::RawAccession| a.id);
    let accessions = accessions.into_iter().assume_sorted_by_key();

    let merged = accessions.join(metadata);

    let mut seen = false;
    for (_id, entry) in merged {
        let (accessions, metadata) = entry;
        let normalized = ds::entry::Normalized::new(metadata, accessions.collect())?;
        serde_json::to_writer(&mut writer, &normalized)?;
        writeln!(&mut writer)?;
        seen = true;
    }

    if !seen {
        return Err(anyhow!("Failed to find any normalized data"));
    }

    Ok(())
}
<|endoftext|>


<commit_before>use std::ops::{Deref, DerefMut};

#[derive(Debug, Clone)]
pub struct Link(String);

impl Deref for Link {
    type Target = String;

    fn deref(&self) -> &String {
        &self.0
    }

}

impl DerefMut for Link {

    fn deref_mut(&mut self) -> &mut String {
        &mut self.0
    }

}
<commit_msg>Add IntoUrl trait for Link type<commit_after>use std::ops::{Deref, DerefMut};

use result::Result;

use url::Url;

#[derive(Debug, Clone)]
pub struct Link(String);

impl Deref for Link {
    type Target = String;

    fn deref(&self) -> &String {
        &self.0
    }

}

impl DerefMut for Link {

    fn deref_mut(&mut self) -> &mut String {
        &mut self.0
    }

}

pub trait IntoUrl {
    fn into_url(self) -> Result<Url>;
}

impl IntoUrl for Link {

    fn into_url(self) -> Result<Url> {
        use error::BookmarkErrorKind as BEK;
        use error::MapErrInto;

        Url::parse(&self[..]).map_err_into(BEK::LinkParsingError)
    }

}

<|endoftext|>


<commit_before>use std::path::PathBuf;
use std::path::Path;
use std::borrow::Borrow;
use std::ops::Deref;

use semver::Version;
use std::fmt::{Display, Debug, Formatter};
use std::fmt::Error as FmtError;
use std::result::Result as RResult;

use error::StoreErrorKind as SEK;
use store::Result;
use store::Store;

/// The Index into the Store
#[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)]
pub struct StoreId {
    base: Option<PathBuf>,
    id:   PathBuf,
}

impl StoreId {

    pub fn new(base: Option<PathBuf>, id: PathBuf) -> StoreId {
        StoreId { base: base, id: id }
    }

    pub fn storified(self, store: &Store) -> StoreId {
        if self.starts_with(store.path()) {
            debug!("Not storifying {:?}, because it is already.", self);
            self
        } else {
            debug!("Create new store id out of: {:?} and {:?}", store.path(), self.id);

            let new_id = StoreId { base: Some(store.path().clone()), self.id };

            debug!("Created: '{:?}'", new_id);
            new_id
        }
    }

    pub fn exists(&self) -> bool {
        let pb : PathBuf = self.clone().into();
        pb.exists()
    }

    pub fn is_file(&self) -> bool {
        true
    }

    pub fn is_dir(&self) -> bool {
        false
    }

}

impl Into<PathBuf> for StoreId {

    fn into(self) -> PathBuf {
        let mut base = self.base.unwrap_or(PathBuf::from("/"));
        base.push(self.id);
        base
    }

}

impl Display for StoreId {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        match self.id.to_str() {
            Some(s) => write!(fmt, "{}", s),
            None    => write!(fmt, "{}", self.id.to_string_lossy()),
        }
    }

}

/// This Trait allows you to convert various representations to a single one
/// suitable for usage in the Store
pub trait IntoStoreId {
    fn into_storeid(self) -> StoreId;
}

impl IntoStoreId for StoreId {
    fn into_storeid(self) -> StoreId {
        self
    }
}

pub fn build_entry_path(store: &Store, path_elem: &str) -> Result<PathBuf> {
    debug!("Checking path element for version");
    if path_elem.split('~').last().map_or(false, |v| Version::parse(v).is_err()) {
        debug!("Version cannot be parsed from {:?}", path_elem);
        debug!("Path does not contain version!");
        return Err(SEK::StorePathLacksVersion.into());
    }
    debug!("Version checking succeeded");

    debug!("Building path from {:?}", path_elem);
    let mut path = store.path().clone();

    if path_elem.starts_with('/') {
        path.push(&path_elem[1..]);
    } else {
        path.push(path_elem);
    }

    Ok(path)
}

#[macro_export]
macro_rules! module_entry_path_mod {
    ($name:expr, $version:expr) => (
        #[deny(missing_docs,
                missing_copy_implementations,
                trivial_casts, trivial_numeric_casts,
                unsafe_code,
                unstable_features,
                unused_import_braces, unused_qualifications,
                unused_imports)]
        /// A helper module to create valid module entry paths
        pub mod module_path {
            use semver::Version;
            use std::convert::AsRef;
            use std::path::Path;
            use std::path::PathBuf;

            use $crate::storeid::StoreId;

            /// A Struct giving you the ability to choose store entries assigned
            /// to it.
            ///
            /// It is created through a call to `new`.
            pub struct ModuleEntryPath(PathBuf);

            impl ModuleEntryPath {
                /// Path has to be a valid UTF-8 string or this will panic!
                pub fn new<P: AsRef<Path>>(pa: P) -> ModuleEntryPath {
                    let mut path = PathBuf::new();
                    path.push(format!("{}", $name));
                    path.push(pa.as_ref().clone());
                    let version = Version::parse($version).unwrap();
                    let name = pa.as_ref().file_name().unwrap()
                        .to_str().unwrap();
                    path.set_file_name(format!("{}~{}",
                                               name,
                                               version));
                    ModuleEntryPath(path)
                }
            }

            impl $crate::storeid::IntoStoreId for ModuleEntryPath {
                fn into_storeid(self) -> $crate::storeid::StoreId {
                    StoreId::new(None, self.0)
                }
            }
        }
    )
}

pub struct StoreIdIterator {
    iter: Box<Iterator<Item = StoreId>>,
}

impl Debug for StoreIdIterator {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "StoreIdIterator")
    }

}

impl StoreIdIterator {

    pub fn new(iter: Box<Iterator<Item = StoreId>>) -> StoreIdIterator {
        StoreIdIterator {
            iter: iter,
        }
    }

}

impl Iterator for StoreIdIterator {
    type Item = StoreId;

    fn next(&mut self) -> Option<StoreId> {
        self.iter.next()
    }

}

#[cfg(test)]
mod test {

    use storeid::IntoStoreId;

    module_entry_path_mod!("test", "0.2.0-alpha+leet1337");

    #[test]
    fn correct_path() {
        let p = module_path::ModuleEntryPath::new("test");

        assert_eq!(p.into_storeid().to_str().unwrap(), "test/test~0.2.0-alpha+leet1337");
    }

}
<commit_msg>Rewrite StoreId::storified()<commit_after>use std::path::PathBuf;
use std::path::Path;
use std::borrow::Borrow;
use std::ops::Deref;

use semver::Version;
use std::fmt::{Display, Debug, Formatter};
use std::fmt::Error as FmtError;
use std::result::Result as RResult;

use error::StoreErrorKind as SEK;
use store::Result;
use store::Store;

/// The Index into the Store
#[derive(Debug, Clone, PartialEq, Hash, Eq, PartialOrd, Ord)]
pub struct StoreId {
    base: Option<PathBuf>,
    id:   PathBuf,
}

impl StoreId {

    pub fn new(base: Option<PathBuf>, id: PathBuf) -> StoreId {
        StoreId { base: base, id: id }
    }

    pub fn storified(self, store: &Store) -> StoreId {
        StoreId {
            base: Some(store.path().clone()),
            id: self.id
        }
    }

    pub fn exists(&self) -> bool {
        let pb : PathBuf = self.clone().into();
        pb.exists()
    }

    pub fn is_file(&self) -> bool {
        true
    }

    pub fn is_dir(&self) -> bool {
        false
    }

}

impl Into<PathBuf> for StoreId {

    fn into(self) -> PathBuf {
        let mut base = self.base.unwrap_or(PathBuf::from("/"));
        base.push(self.id);
        base
    }

}

impl Display for StoreId {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        match self.id.to_str() {
            Some(s) => write!(fmt, "{}", s),
            None    => write!(fmt, "{}", self.id.to_string_lossy()),
        }
    }

}

/// This Trait allows you to convert various representations to a single one
/// suitable for usage in the Store
pub trait IntoStoreId {
    fn into_storeid(self) -> StoreId;
}

impl IntoStoreId for StoreId {
    fn into_storeid(self) -> StoreId {
        self
    }
}

pub fn build_entry_path(store: &Store, path_elem: &str) -> Result<PathBuf> {
    debug!("Checking path element for version");
    if path_elem.split('~').last().map_or(false, |v| Version::parse(v).is_err()) {
        debug!("Version cannot be parsed from {:?}", path_elem);
        debug!("Path does not contain version!");
        return Err(SEK::StorePathLacksVersion.into());
    }
    debug!("Version checking succeeded");

    debug!("Building path from {:?}", path_elem);
    let mut path = store.path().clone();

    if path_elem.starts_with('/') {
        path.push(&path_elem[1..]);
    } else {
        path.push(path_elem);
    }

    Ok(path)
}

#[macro_export]
macro_rules! module_entry_path_mod {
    ($name:expr, $version:expr) => (
        #[deny(missing_docs,
                missing_copy_implementations,
                trivial_casts, trivial_numeric_casts,
                unsafe_code,
                unstable_features,
                unused_import_braces, unused_qualifications,
                unused_imports)]
        /// A helper module to create valid module entry paths
        pub mod module_path {
            use semver::Version;
            use std::convert::AsRef;
            use std::path::Path;
            use std::path::PathBuf;

            use $crate::storeid::StoreId;

            /// A Struct giving you the ability to choose store entries assigned
            /// to it.
            ///
            /// It is created through a call to `new`.
            pub struct ModuleEntryPath(PathBuf);

            impl ModuleEntryPath {
                /// Path has to be a valid UTF-8 string or this will panic!
                pub fn new<P: AsRef<Path>>(pa: P) -> ModuleEntryPath {
                    let mut path = PathBuf::new();
                    path.push(format!("{}", $name));
                    path.push(pa.as_ref().clone());
                    let version = Version::parse($version).unwrap();
                    let name = pa.as_ref().file_name().unwrap()
                        .to_str().unwrap();
                    path.set_file_name(format!("{}~{}",
                                               name,
                                               version));
                    ModuleEntryPath(path)
                }
            }

            impl $crate::storeid::IntoStoreId for ModuleEntryPath {
                fn into_storeid(self) -> $crate::storeid::StoreId {
                    StoreId::new(None, self.0)
                }
            }
        }
    )
}

pub struct StoreIdIterator {
    iter: Box<Iterator<Item = StoreId>>,
}

impl Debug for StoreIdIterator {

    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "StoreIdIterator")
    }

}

impl StoreIdIterator {

    pub fn new(iter: Box<Iterator<Item = StoreId>>) -> StoreIdIterator {
        StoreIdIterator {
            iter: iter,
        }
    }

}

impl Iterator for StoreIdIterator {
    type Item = StoreId;

    fn next(&mut self) -> Option<StoreId> {
        self.iter.next()
    }

}

#[cfg(test)]
mod test {

    use storeid::IntoStoreId;

    module_entry_path_mod!("test", "0.2.0-alpha+leet1337");

    #[test]
    fn correct_path() {
        let p = module_path::ModuleEntryPath::new("test");

        assert_eq!(p.into_storeid().to_str().unwrap(), "test/test~0.2.0-alpha+leet1337");
    }

}
<|endoftext|>


<commit_before>#![allow(noop_method_call)]

#[test]
fn test_borrowed_clone() {
    let x = 5;
    let y: &i32 = &x;
    let z: &i32 = (&y).clone();
    assert_eq!(*z, 5);
}

#[test]
fn test_clone_from() {
    let a = box 5;
    let mut b = box 10;
    b.clone_from(&a);
    assert_eq!(*b, 5);
}
<commit_msg>Only allow new lint when not bootstrapping - since beta doesn't know about the lint<commit_after>#![cfg_attr(not(bootstrap), allow(noop_method_call))]

#[test]
fn test_borrowed_clone() {
    let x = 5;
    let y: &i32 = &x;
    let z: &i32 = (&y).clone();
    assert_eq!(*z, 5);
}

#[test]
fn test_clone_from() {
    let a = box 5;
    let mut b = box 10;
    b.clone_from(&a);
    assert_eq!(*b, 5);
}
<|endoftext|>


<commit_before>#[macro_use]
pub mod utility;

pub mod streaminfo;
pub mod comments;
pub mod seektable;
pub mod picture;
<commit_msg>Remove public exporting of utility module<commit_after>#[macro_use]
mod utility;

pub mod streaminfo;
pub mod comments;
pub mod seektable;
pub mod picture;
<|endoftext|>


<commit_before>extern crate piston_window;

use piston_window::*;

fn main() {
    let title = "Hello Piston! (press any key to enter inner loop)";
    let mut window: PistonWindow = WindowSettings::new(title, [640, 480])
        .exit_on_esc(true)
        .build()
        .unwrap_or_else(|e| { panic!("Failed to build PistonWindow: {}", e) });
    while let Some(e) = window.next() {
        window.draw_2d(&e, |c, g| {
            clear([0.5, 1.0, 0.5, 1.0], g);
            rectangle([1.0, 0.0, 0.0, 1.0], [50.0, 50.0, 100.0, 100.0], c.transform, g);
        });

        if e.press_args().is_some() {
            window.set_title("Inner loop (press X to exit inner loop)".into());
            while let Some(e) = window.next() {
                window.draw_2d(&e, |c, g| {
                    clear([0.5, 0.5, 1.0, 1.0], g);
                    ellipse([1.0, 0.0, 0.0, 1.0], [50.0, 50.0, 100.0, 100.0], c.transform, g);
                });

                // Inner loop.
                if let Some(Button::Keyboard(Key::X)) = e.press_args() {
                    break;
                }
            }
            window.set_title(title.into());
        }
    }
}
<commit_msg>Show how to change app state in hello_piston<commit_after>extern crate piston_window;

use piston_window::*;

fn main() {
    let title = "Hello Piston! (press any key to enter inner loop)";
    let mut window: PistonWindow = WindowSettings::new(title, [640, 480])
        .exit_on_esc(true)
        .build()
        .unwrap_or_else(|e| { panic!("Failed to build PistonWindow: {}", e) });
    while let Some(e) = window.next() {
        window.draw_2d(&e, |c, g| {
            clear([0.5, 1.0, 0.5, 1.0], g);
            rectangle([1.0, 0.0, 0.0, 1.0], [50.0, 50.0, 100.0, 100.0], c.transform, g);
        });

        if e.press_args().is_some() {
            window = inner_event_loop(window.app(InnerApp {
                title: "Inner loop (press X to exit inner loop)",
                exit_button: Button::Keyboard(Key::X),
            }));
            window.set_title(title.into());
        }
    }
}

/// Stores application state of inner event loop.
pub struct InnerApp {
    pub title: &'static str,
    pub exit_button: Button,
}

fn inner_event_loop(mut window: PistonWindow<InnerApp>) -> PistonWindow {
    window.set_title(window.app.title.into());
    while let Some(e) = window.next() {
        window.draw_2d(&e, |c, g| {
            clear([0.5, 0.5, 1.0, 1.0], g);
            ellipse([1.0, 0.0, 0.0, 1.0], [50.0, 50.0, 100.0, 100.0], c.transform, g);
        });
        if let Some(button) = e.press_args() {
            if button == window.app.exit_button {
                break;
            }
        }
    }

    // Go back to default app state.
    window.app(())
}
<|endoftext|>


<commit_before>// This example implements an OCR (optical character recognition):
// https://en.wikipedia.org/wiki/Optical_character_recognition
// using an evolutionary algorithm.
//
// Note that evolutionary algorithms do no guarantee to always find the optimal solution.
// But they can get very close.

extern crate rand;
extern crate image;
extern crate imageproc;
extern crate rusttype;
#[macro_use] extern crate lazy_static;
extern crate simplelog;

// internal crates
extern crate darwin_rs;

use rand::Rng;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use image::{GenericImage, ImageBuffer, Luma};
use image::imageops::replace;
use imageproc::stats::root_mean_squared_error;
use simplelog::{SimpleLogger, LogLevelFilter};
use std::sync::Mutex;
use std::str;

// internal modules
use darwin_rs::{Individual, SimulationBuilder, PopulationBuilder, SimError};

lazy_static!{
    static ref FONT: rusttype::Font<'static>  = {
        // TODO: use fontconfig-rs in the future: https://github.com/abonander/fontconfig-rs
        let mut file = File::open("/usr/share/fonts/truetype/liberation/LiberationMono-Regular.ttf").unwrap();
        let mut font_data: Vec<u8> = Vec::new();
        let bytes_read = file.read_to_end(&mut font_data).unwrap();
        println!("bytes read: {}", bytes_read);

        let collection = rusttype::FontCollection::from_bytes(font_data);
        let font = collection.into_font().unwrap();
        font
    };
}

lazy_static! {
    static ref ORIGINAL_IMG: Mutex<ImageBuffer<Luma<u8>, Vec<u8>>> = {
        let original_img: ImageBuffer<Luma<u8>, Vec<u8>> = ImageBuffer::new(640, 70);
        Mutex::new(original_img)
    };
}

#[derive(Debug, Clone)]
struct TextBox {
    x: u32,
    y: u32,
    text: Vec<u8>,
}

#[derive(Debug, Clone)]
struct OCRItem {
    content: Vec<TextBox>,
}

impl Individual for OCRItem {
    fn new() -> OCRItem {
        OCRItem { content: Vec::new() }
    }

    fn mutate(&mut self) {
        let mut rng = rand::thread_rng();

        let operation: u8 = rng.gen_range(0, 6);

        match operation {
            0 => { // Add a new empty text box
                self.content.push( TextBox{ x: 0, y: 0, text: Vec::new() } );
            },
            1 => { // Remove a text box
                if self.content.len() > 1 { // Leave at least one text box.
                    let remove_index = rng.gen_range(0, self.content.len());
                    let _ = self.content.remove(remove_index as usize);
                }
            },
            2 => { // Move the text box around
                if self.content.len() > 0 {
                    let move_index = rng.gen_range(0, self.content.len());
                    let canvas = ORIGINAL_IMG.lock().unwrap();
                    let new_x = rng.gen_range(0, canvas.width());
                    let new_y = rng.gen_range(0, canvas.height());

                    self.content[move_index].x = new_x;
                    self.content[move_index].y = new_y;
                }
            },
            3 => { // Add a random character to the text box
                if self.content.len() > 0 {
                    let content_index = rng.gen_range(0, self.content.len());
                    let add_char_index = if self.content[content_index].text.is_empty() { 0 }
                        else { rng.gen_range(0, self.content[content_index].text.len()) };
                    let random_ascii_value: u8 = rng.gen_range(33, 127);

                    self.content[content_index].text.insert(add_char_index, random_ascii_value);
                }
            },
            4 => { // Remove a character from the text box
                if self.content.len() > 0 {
                    let content_index = rng.gen_range(0, self.content.len());
                    if self.content[content_index].text.len() > 1 { // Leave at least one char
                        let remove_char_index = rng.gen_range(0, self.content[content_index].text.len());
                        self.content[content_index].text.remove(remove_char_index);

                    }
                }
            },
            5 => { // Swap two characters inside a text box
                if self.content.len() > 0 {
                    let content_index = rng.gen_range(0, self.content.len());
                    if self.content[content_index].text.len() > 1 { // Need at least two chars to swap
                        let index1: usize = rng.gen_range(0, self.content[content_index].text.len());
                        let index2: usize = rng.gen_range(0, self.content[content_index].text.len());
                        let tmp_char = self.content[content_index].text[index1];
                        self.content[content_index].text[index1] = self.content[content_index].text[index2];
                        self.content[content_index].text[index2] = tmp_char;
                    }
                }
            },
            _ => println!("unknown operation: {}", operation),
        }
    }

    fn calculate_fitness(&self) -> f64 {
        let mut constructed_img: ImageBuffer<Luma<u8>, Vec<u8>> = ImageBuffer::new(640, 70);

        for text_box in self.content.iter() {
            match str::from_utf8(&text_box.text) {
                Ok(text) => draw_text_line(&mut constructed_img, &FONT, text_box.x as i32,
                    text_box.y as i32, text),
                _ => {} // Do nothing for now
            }
        }

        let canvas = ORIGINAL_IMG.lock().unwrap();

        root_mean_squared_error(&*canvas, &constructed_img)
    }
}

fn draw_text_line(canvas: &mut ImageBuffer<Luma<u8>, Vec<u8>>,
                  font: &rusttype::Font,
                  pos_x: i32,
                  pos_y: i32,
                  text: &str) {

    // println!("text: {}", text);

    let height: f32 = 18.0;

    let scale = rusttype::Scale { x: height * 1.0, y: height };
    let v_metrics = font.v_metrics(scale);
    let offset = rusttype::point(0.0, v_metrics.ascent);
    let glyphs: Vec<rusttype::PositionedGlyph> = font.layout(text, scale, offset).collect();

    for g in glyphs {
        if let Some(bb) = g.pixel_bounding_box() {
            g.draw(|x, y, v| {
                let x = ((x as i32) + bb.min.x + pos_x) as u32;
                let y = ((y as i32) + bb.min.y + pos_y) as u32;
                if x < canvas.width() && y < canvas.height() {
                    canvas.put_pixel(x, y, Luma::<u8>{ data: [(v * 255.0) as u8] } );
                }
            })
        }
    }

}

fn main() {
    println!("Darwin test: optical character recognition");

    let _ = SimpleLogger::init(LogLevelFilter::Info);

    {
        let mut canvas = ORIGINAL_IMG.lock().unwrap();

        draw_text_line(&mut canvas, &FONT, 10, 10, "This is a test text!");
        draw_text_line(&mut canvas, &FONT, 10, 40, "Just to see how good OCR works...");

        let img_file = Path::new("rendered_text.png");
        let _ = canvas.save(&img_file);
    }

    let population1 = PopulationBuilder::<OCRItem>::new()
        .set_id(1)
        .individuals(100)
        .increasing_exp_mutation_rate(1.1)
        .reset_limit_increment(100)
        .reset_limit_start(100)
        .reset_limit_end(1000)
        .finalize().unwrap();

    let population2 = PopulationBuilder::<OCRItem>::new()
        .set_id(2)
        .individuals(100)
        .increasing_exp_mutation_rate(1.2)
        .reset_limit_increment(200)
        .reset_limit_start(100)
        .reset_limit_end(2000)
        .finalize().unwrap();

    let ocr_builder = SimulationBuilder::<OCRItem>::new()
        .fitness(10.0)
        .threads(4)
        .add_population(population1)
        .add_population(population2)
        .finalize();

    match ocr_builder {
        Err(SimError::EndIterationTooLow) => println!("more than 10 iteratons needed"),
        Ok(mut ocr_simulation) => {
            ocr_simulation.run();

            println!("total run time: {} ms", ocr_simulation.total_time_in_ms);
            println!("improvement factor: {}", ocr_simulation.simulation_result.improvement_factor);
            println!("number of iterations: {}", ocr_simulation.simulation_result.iteration_counter);

            ocr_simulation.print_fitness();

            for content in ocr_simulation.simulation_result.fittest[0].individual.content.iter() {
                println!("x: {}, y: {}, text: {}", content.x, content.y, str::from_utf8(&content.text).unwrap())
            }
        }
    }
}
<commit_msg>adjust simulation parameters<commit_after>// This example implements an OCR (optical character recognition):
// https://en.wikipedia.org/wiki/Optical_character_recognition
// using an evolutionary algorithm.
//
// Note that evolutionary algorithms do no guarantee to always find the optimal solution.
// But they can get very close.

extern crate rand;
extern crate image;
extern crate imageproc;
extern crate rusttype;
#[macro_use] extern crate lazy_static;
extern crate simplelog;

// internal crates
extern crate darwin_rs;

use rand::Rng;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use image::{ImageBuffer, Luma};
use imageproc::stats::root_mean_squared_error;
use simplelog::{SimpleLogger, LogLevelFilter};
use std::sync::Mutex;
use std::str;

// internal modules
use darwin_rs::{Individual, SimulationBuilder, PopulationBuilder, SimError};

lazy_static!{
    static ref FONT: rusttype::Font<'static>  = {
        // TODO: use fontconfig-rs in the future: https://github.com/abonander/fontconfig-rs
        let mut file = File::open("/usr/share/fonts/truetype/liberation/LiberationMono-Regular.ttf").unwrap();
        let mut font_data: Vec<u8> = Vec::new();
        let bytes_read = file.read_to_end(&mut font_data).unwrap();
        println!("bytes read: {}", bytes_read);

        let collection = rusttype::FontCollection::from_bytes(font_data);
        let font = collection.into_font().unwrap();
        font
    };
}

lazy_static! {
    static ref ORIGINAL_IMG: Mutex<ImageBuffer<Luma<u8>, Vec<u8>>> = {
        let original_img: ImageBuffer<Luma<u8>, Vec<u8>> = ImageBuffer::new(640, 70);
        Mutex::new(original_img)
    };
}

#[derive(Debug, Clone)]
struct TextBox {
    x: u32,
    y: u32,
    text: Vec<u8>,
}

#[derive(Debug, Clone)]
struct OCRItem {
    content: Vec<TextBox>,
}

impl Individual for OCRItem {
    fn new() -> OCRItem {
        OCRItem { content: Vec::new() }
    }

    fn mutate(&mut self) {
        let mut rng = rand::thread_rng();

        let operation: u8 = rng.gen_range(0, 6);

        match operation {
            0 => { // Add a new empty text box
                self.content.push( TextBox{ x: 0, y: 0, text: Vec::new() } );
            },
            1 => { // Remove a text box
                if self.content.len() > 1 { // Leave at least one text box.
                    let remove_index = rng.gen_range(0, self.content.len());
                    let _ = self.content.remove(remove_index as usize);
                }
            },
            2 => { // Move the text box around
                if self.content.len() > 0 {
                    let move_index = rng.gen_range(0, self.content.len());
                    let canvas = ORIGINAL_IMG.lock().unwrap();
                    let new_x = rng.gen_range(0, canvas.width());
                    let new_y = rng.gen_range(0, canvas.height());

                    self.content[move_index].x = new_x;
                    self.content[move_index].y = new_y;
                }
            },
            3 => { // Add a random character to the text box
                if self.content.len() > 0 {
                    let content_index = rng.gen_range(0, self.content.len());
                    let add_char_index = if self.content[content_index].text.is_empty() { 0 }
                        else { rng.gen_range(0, self.content[content_index].text.len()) };
                    let random_ascii_value: u8 = rng.gen_range(33, 127);

                    self.content[content_index].text.insert(add_char_index, random_ascii_value);
                }
            },
            4 => { // Remove a character from the text box
                if self.content.len() > 0 {
                    let content_index = rng.gen_range(0, self.content.len());
                    if self.content[content_index].text.len() > 1 { // Leave at least one char
                        let remove_char_index = rng.gen_range(0, self.content[content_index].text.len());
                        self.content[content_index].text.remove(remove_char_index);

                    }
                }
            },
            5 => { // Swap two characters inside a text box
                if self.content.len() > 0 {
                    let content_index = rng.gen_range(0, self.content.len());
                    if self.content[content_index].text.len() > 1 { // Need at least two chars to swap
                        let index1: usize = rng.gen_range(0, self.content[content_index].text.len());
                        let index2: usize = rng.gen_range(0, self.content[content_index].text.len());
                        let tmp_char = self.content[content_index].text[index1];
                        self.content[content_index].text[index1] = self.content[content_index].text[index2];
                        self.content[content_index].text[index2] = tmp_char;
                    }
                }
            },
            _ => println!("unknown operation: {}", operation),
        }
    }

    fn calculate_fitness(&self) -> f64 {
        let mut constructed_img: ImageBuffer<Luma<u8>, Vec<u8>> = ImageBuffer::new(640, 70);

        for text_box in self.content.iter() {
            match str::from_utf8(&text_box.text) {
                Ok(text) => draw_text_line(&mut constructed_img, &FONT, text_box.x as i32,
                    text_box.y as i32, text),
                _ => {} // Do nothing for now
            }
        }

        let canvas = ORIGINAL_IMG.lock().unwrap();

        root_mean_squared_error(&*canvas, &constructed_img)
    }
}

fn draw_text_line(canvas: &mut ImageBuffer<Luma<u8>, Vec<u8>>,
                  font: &rusttype::Font,
                  pos_x: i32,
                  pos_y: i32,
                  text: &str) {

    // println!("text: {}", text);

    let height: f32 = 18.0;

    let scale = rusttype::Scale { x: height * 1.0, y: height };
    let v_metrics = font.v_metrics(scale);
    let offset = rusttype::point(0.0, v_metrics.ascent);
    let glyphs: Vec<rusttype::PositionedGlyph> = font.layout(text, scale, offset).collect();

    for g in glyphs {
        if let Some(bb) = g.pixel_bounding_box() {
            g.draw(|x, y, v| {
                let x = ((x as i32) + bb.min.x + pos_x) as u32;
                let y = ((y as i32) + bb.min.y + pos_y) as u32;
                if x < canvas.width() && y < canvas.height() {
                    canvas.put_pixel(x, y, Luma::<u8>{ data: [(v * 255.0) as u8] } );
                }
            })
        }
    }

}

fn main() {
    println!("Darwin test: optical character recognition");

    let _ = SimpleLogger::init(LogLevelFilter::Info);

    {
        let mut canvas = ORIGINAL_IMG.lock().unwrap();

        draw_text_line(&mut canvas, &FONT, 10, 10, "This is a test text!");
        draw_text_line(&mut canvas, &FONT, 10, 40, "Just to see how good OCR works...");

        let img_file = Path::new("rendered_text.png");
        let _ = canvas.save(&img_file);
    }

    let population1 = PopulationBuilder::<OCRItem>::new()
        .set_id(1)
        .individuals(30)
        .increasing_exp_mutation_rate(1.1)
        .reset_limit_increment(100)
        .reset_limit_start(100)
        .reset_limit_end(1000)
        .finalize().unwrap();

    let population2 = PopulationBuilder::<OCRItem>::new()
        .set_id(2)
        .individuals(30)
        .increasing_exp_mutation_rate(1.15)
        .reset_limit_increment(200)
        .reset_limit_start(100)
        .reset_limit_end(2000)
        .finalize().unwrap();

    let population3 = PopulationBuilder::<OCRItem>::new()
        .set_id(3)
        .individuals(30)
        .increasing_exp_mutation_rate(1.2)
        .reset_limit_increment(300)
        .reset_limit_start(100)
        .reset_limit_end(3000)
        .finalize().unwrap();

    let ocr_builder = SimulationBuilder::<OCRItem>::new()
        .fitness(10.0)
        .threads(2)
        .add_population(population1)
        .add_population(population2)
        .add_population(population3)
        .finalize();

    match ocr_builder {
        Err(SimError::EndIterationTooLow) => println!("more than 10 iteratons needed"),
        Ok(mut ocr_simulation) => {
            ocr_simulation.run();

            println!("total run time: {} ms", ocr_simulation.total_time_in_ms);
            println!("improvement factor: {}", ocr_simulation.simulation_result.improvement_factor);
            println!("number of iterations: {}", ocr_simulation.simulation_result.iteration_counter);

            ocr_simulation.print_fitness();

            for content in ocr_simulation.simulation_result.fittest[0].individual.content.iter() {
                println!("x: {}, y: {}, text: {}", content.x, content.y, str::from_utf8(&content.text).unwrap())
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2019, Cloudflare, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#[macro_use]
extern crate log;

use std::fs::File;

use std::io::prelude::*;
use std::io::BufReader;

use quiche::h3;

fn main() {
    let mut args = std::env::args();

    let cmd = &args.next().unwrap();

    if args.len() != 1 {
        println!("Usage: {} FILE", cmd);
        return;
    }

    let file = File::open(&args.next().unwrap()).unwrap();
    let file = BufReader::new(&file);

    let mut enc = h3::qpack::Encoder::new();

    let mut headers: Vec<h3::Header> = Vec::new();

    let mut stream_id = 1u64;

    for line in file.lines().map(Result::unwrap) {
        if line.starts_with('#') {
            continue;
        }

        if line.is_empty() {
            let mut out = [0u8; 65535];

            let len = enc.encode(&headers, &mut out).unwrap();

            debug!("Writing header block stream={} len={}", stream_id, len);

            std::io::stdout()
                .write_all(&stream_id.to_be_bytes())
                .unwrap();
            std::io::stdout()
                .write_all(&(len as u32).to_be_bytes())
                .unwrap();
            std::io::stdout().write_all(&out[..len]).unwrap();

            stream_id += 1;

            headers.clear();

            continue;
        }

        let name = line.split('\t').nth(0).unwrap();
        let value = line.split('\t').last().unwrap();

        headers.push(h3::Header::new(name, value));
    }
}
<commit_msg>examples: fix clippy warning in qpack-encode<commit_after>// Copyright (C) 2019, Cloudflare, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#[macro_use]
extern crate log;

use std::fs::File;

use std::io::prelude::*;
use std::io::BufReader;

use quiche::h3;

fn main() {
    let mut args = std::env::args();

    let cmd = &args.next().unwrap();

    if args.len() != 1 {
        println!("Usage: {} FILE", cmd);
        return;
    }

    let file = File::open(&args.next().unwrap()).unwrap();
    let file = BufReader::new(&file);

    let mut enc = h3::qpack::Encoder::new();

    let mut headers: Vec<h3::Header> = Vec::new();

    let mut stream_id = 1u64;

    for line in file.lines().map(Result::unwrap) {
        if line.starts_with('#') {
            continue;
        }

        if line.is_empty() {
            let mut out = [0u8; 65535];

            let len = enc.encode(&headers, &mut out).unwrap();

            debug!("Writing header block stream={} len={}", stream_id, len);

            std::io::stdout()
                .write_all(&stream_id.to_be_bytes())
                .unwrap();
            std::io::stdout()
                .write_all(&(len as u32).to_be_bytes())
                .unwrap();
            std::io::stdout().write_all(&out[..len]).unwrap();

            stream_id += 1;

            headers.clear();

            continue;
        }

        let name = line.split('\t').next().unwrap();
        let value = line.split('\t').last().unwrap();

        headers.push(h3::Header::new(name, value));
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2016  ParadoxSpiral
//
// This file is part of mpv-rs.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

use mpv;
use mpv::{Data, MpvInstance, MpvError, Parent, Property, PlaylistOp};
use mpv::utils;
use mpv::protocol::*;

use std::fs::File;
use std::io::{Read, Seek, SeekFrom};
use std::mem;
use std::path::Path;
use std::slice;
use std::time::Duration;
use std::thread;

fn open(cookie: *mut File, _: &(), uri: &str) -> Result<(), MpvError> {
	unsafe {
		// Strip the `filereader://` part
		*cookie = File::open(&uri[13..]).unwrap()
	};
	println!("Opened file, ready for orders o7");
	Ok(())
}

fn close(_: Box<File>) {
	println!("Closing file, bye bye~~");
}

fn read(cookie: *mut File, buf: *mut i8, nbytes: u64) -> i64 {
	unsafe {
		let slice = slice::from_raw_parts_mut(buf, nbytes as _);
		let forbidden_magic = mem::transmute::<&mut [i8], &mut [u8]>(slice);

		(*cookie).read(forbidden_magic).unwrap() as _
	}
}

fn seek(cookie: *mut File, offset: i64) -> i64 {
	unsafe {
		(&mut (*cookie)).seek(SeekFrom::Start(offset as u64)).unwrap() as _
	}
}

fn size(cookie: *mut File) -> i64 {
	unsafe {
		(*cookie).metadata().unwrap().len() as _
	}
}

pub fn exec() {
	let path = format!("filereader://{}", ::std::env::args().nth(1).unwrap());

	let protocol = unsafe {
		Protocol::new("filereader".into(), (), box open, box close,
					  box read, Some(box seek), Some(box size))
	};

	let mpv = Parent::new(false).unwrap();
	mpv.register_protocol(protocol).unwrap();

	mpv.set_property(Property::new("volume", Data::new(40))).unwrap();

	mpv.playlist(&PlaylistOp::Loadfiles(&[utils::File::new(Path::new(&path),
	                                                        utils::FileState::AppendPlay,
	                                                        None)]))
	           .unwrap();

	thread::sleep(Duration::from_secs(10));

	mpv.seek(&mpv::Seek::RelativeForward(Duration::from_secs(15))).unwrap();

	thread::sleep(Duration::from_secs(5));
}
<commit_msg>rustfmt<commit_after>// Copyright (C) 2016  ParadoxSpiral
//
// This file is part of mpv-rs.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

use mpv;
use mpv::{Data, MpvInstance, MpvError, Parent, Property, PlaylistOp};
use mpv::utils;
use mpv::protocol::*;

use std::fs::File;
use std::io::{Read, Seek, SeekFrom};
use std::mem;
use std::path::Path;
use std::slice;
use std::time::Duration;
use std::thread;

fn open(cookie: *mut File, _: &(), uri: &str) -> Result<(), MpvError> {
    unsafe {
        // Strip the `filereader://` part
        *cookie = File::open(&uri[13..]).unwrap()
    };
    println!("Opened file, ready for orders o7");
    Ok(())
}

fn close(_: Box<File>) {
    println!("Closing file, bye bye~~");
}

fn read(cookie: *mut File, buf: *mut i8, nbytes: u64) -> i64 {
    unsafe {
        let slice = slice::from_raw_parts_mut(buf, nbytes as _);
        let forbidden_magic = mem::transmute::<&mut [i8], &mut [u8]>(slice);

        (*cookie).read(forbidden_magic).unwrap() as _
    }
}

fn seek(cookie: *mut File, offset: i64) -> i64 {
    unsafe { (&mut (*cookie)).seek(SeekFrom::Start(offset as u64)).unwrap() as _ }
}

fn size(cookie: *mut File) -> i64 {
    unsafe { (*cookie).metadata().unwrap().len() as _ }
}

pub fn exec() {
    let path = format!("filereader://{}", ::std::env::args().nth(1).unwrap());

    let protocol = unsafe {
        Protocol::new("filereader".into(),
                      (),
                      box open,
                      box close,
                      box read,
                      Some(box seek),
                      Some(box size))
    };

    let mpv = Parent::new(false).unwrap();
    mpv.register_protocol(protocol).unwrap();

    mpv.set_property(Property::new("volume", Data::new(40))).unwrap();

    mpv.playlist(&PlaylistOp::Loadfiles(&[utils::File::new(Path::new(&path),
                                                           utils::FileState::AppendPlay,
                                                           None)]))
       .unwrap();

    thread::sleep(Duration::from_secs(10));

    mpv.seek(&mpv::Seek::RelativeForward(Duration::from_secs(15))).unwrap();

    thread::sleep(Duration::from_secs(5));
}
<|endoftext|>


<commit_before>//! Implementation of a simple uTP client and server.

extern crate utp;
use std::old_io::net::ip::{Ipv4Addr, SocketAddr};

macro_rules! iotry {
    ($e:expr) => (match $e { Ok(v) => v, Err(e) => panic!("{}", e), })
}

fn usage() {
    println!("Usage: utp [-s|-c] <address> <port>");
}

fn main() {
    use utp::UtpStream;
    use std::str::FromStr;
    use std::io::{stdin, stdout, stderr, Read, Write};

    enum Mode {
        Server,
        Client
    }
    let mut mode: Mode;

    // Provide a default address
    let mut addr = SocketAddr { ip: Ipv4Addr(127,0,0,1), port: 8080 };

    let args = std::os::args();
    let mut args = args.iter().map(|arg| &arg[..]);

    // Skip program name
    args.next();

    match args.next() {
        Some("-s") => mode = Mode::Server,
        Some("-c") => mode = Mode::Client,
        _ => { usage(); return; }
    }

    match &args.collect::<Vec<_>>()[..] {
        [] => (),
        [ip, port] => {
            let ip = match FromStr::from_str(ip) {
                Ok(x) => x,
                Err(_) => { println!("Invalid address"); return }
            };
            let port = match FromStr::from_str(port) {
                Ok(x) => x,
                Err(_) => { println!("Invalid port"); return }
            };
            addr = SocketAddr {
                ip:   ip,
                port: port,
            };
        }
        _ => { usage(); return; }
    }

    match mode {
        Mode::Server => {
            let mut stream = UtpStream::bind(addr);
            let mut writer = stdout();
            let _ = writeln!(&mut stderr(), "Serving on {}", addr);

            let payload = iotry!(stream.read_to_end());
            iotry!(writer.write(&payload[..]));
        }
        Mode::Client => {
            let mut stream = iotry!(UtpStream::connect(addr));
            let mut reader = stdin();

            let mut payload = vec!();
            iotry!(reader.read_to_end(&mut payload));
            iotry!(stream.write(&payload[..]));
            iotry!(stream.close());
            drop(stream);
        }
    }
}
<commit_msg>Avoid mutable variables.<commit_after>//! Implementation of a simple uTP client and server.

extern crate utp;
use std::old_io::net::ip::{Ipv4Addr, SocketAddr};

macro_rules! iotry {
    ($e:expr) => (match $e { Ok(v) => v, Err(e) => panic!("{}", e), })
}

fn usage() {
    println!("Usage: utp [-s|-c] <address> <port>");
}

fn main() {
    use utp::UtpStream;
    use std::str::FromStr;
    use std::io::{stdin, stdout, stderr, Read, Write};

    enum Mode {
        Server,
        Client
    }

    let args = std::os::args();
    let mut args = args.iter().map(|arg| &arg[..]);

    // Skip program name
    args.next();

    let mode = match args.next() {
        Some("-s") => Mode::Server,
        Some("-c") => Mode::Client,
        _ => { usage(); return; }
    };

    let addr = match &args.collect::<Vec<_>>()[..] {
        [] => {
            // Use a default address
            SocketAddr { ip: Ipv4Addr(127,0,0,1), port: 8080 }
        },
        [ip, port] => {
            let ip = match FromStr::from_str(ip) {
                Ok(x) => x,
                Err(_) => { println!("Invalid address"); return }
            };
            let port = match FromStr::from_str(port) {
                Ok(x) => x,
                Err(_) => { println!("Invalid port"); return }
            };
            SocketAddr {
                ip:   ip,
                port: port,
            }
        }
        _ => { usage(); return; }
    };

    match mode {
        Mode::Server => {
            let mut stream = UtpStream::bind(addr);
            let mut writer = stdout();
            let _ = writeln!(&mut stderr(), "Serving on {}", addr);

            let payload = iotry!(stream.read_to_end());
            iotry!(writer.write(&payload[..]));
        }
        Mode::Client => {
            let mut stream = iotry!(UtpStream::connect(addr));
            let mut reader = stdin();

            let mut payload = vec!();
            iotry!(reader.read_to_end(&mut payload));
            iotry!(stream.write(&payload[..]));
            iotry!(stream.close());
            drop(stream);
        }
    }
}
<|endoftext|>


<commit_before>//  Copyright (C) 2020 Éloïs SANCHEZ.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

use crate::*;
use async_graphql::connection::*;
use duniter_gva_dbs_reader::{
    utxos::{UtxoCursor, UtxosWithSum},
    PagedData,
};

#[derive(Default)]
pub(crate) struct UtxosQuery;
#[async_graphql::Object]
impl UtxosQuery {
    /// Transactions history
    async fn utxos_of_script(
        &self,
        ctx: &async_graphql::Context<'_>,
        #[graphql(desc = "DUBP wallet script")] script: PkOrScriptGva,
        #[graphql(desc = "pagination", default)] pagination: Pagination,
        #[graphql(desc = "Amount needed")] amount: Option<i64>,
    ) -> async_graphql::Result<Connection<String, UtxoGva, AggregateSum, EmptyFields>> {
        let QueryContext { is_whitelisted } = ctx.data::<QueryContext>()?;
        log::info!("is_whitelisted={}", is_whitelisted);
        let pagination = Pagination::convert_to_page_info(pagination, *is_whitelisted)?;

        let data = ctx.data::<GvaSchemaData>()?;
        let db_reader = data.dbs_reader();

        let (
            PagedData {
                data: UtxosWithSum { utxos, sum },
                has_previous_page,
                has_next_page,
            },
            times,
        ) = data
            .dbs_pool
            .execute(move |dbs| {
                if let Some(current_block) = duniter_bc_reader::get_current_block_meta(&dbs.cm_db)?
                {
                    let paged_data = db_reader.find_script_utxos(
                        &dbs.txs_mp_db,
                        amount.map(|amount| {
                            SourceAmount::new(amount, current_block.unit_base as i64)
                        }),
                        pagination,
                        &script.0,
                    )?;
                    let mut times = Vec::with_capacity(paged_data.data.utxos.len());
                    for (UtxoCursor { block_number, .. }, _sa) in &paged_data.data.utxos {
                        times.push(db_reader.get_blockchain_time(*block_number)?);
                    }
                    Ok::<_, anyhow::Error>((paged_data, times))
                } else {
                    Err(anyhow::Error::msg("no blockchain"))
                }
            })
            .await??;

        let mut conn = Connection::with_additional_fields(
            has_previous_page,
            has_next_page,
            AggregateSum {
                aggregate: Sum {
                    sum: AmountWithBase {
                        amount: sum.amount() as i32,
                        base: sum.base() as i32,
                    },
                },
            },
        );
        conn.append(utxos.into_iter().zip(times.into_iter()).map(
            |((utxo_cursor, source_amount), blockchain_time)| {
                Edge::new(
                    utxo_cursor.to_string(),
                    UtxoGva {
                        amount: source_amount.amount(),
                        base: source_amount.base(),
                        tx_hash: utxo_cursor.tx_hash.to_hex(),
                        output_index: utxo_cursor.output_index as u32,
                        written_block: utxo_cursor.block_number.0,
                        written_time: blockchain_time,
                    },
                )
            },
        ));
        Ok(conn)
    }
}
<commit_msg>[doc] gva: fix desc of query utxosOfScript<commit_after>//  Copyright (C) 2020 Éloïs SANCHEZ.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

use crate::*;
use async_graphql::connection::*;
use duniter_gva_dbs_reader::{
    utxos::{UtxoCursor, UtxosWithSum},
    PagedData,
};

#[derive(Default)]
pub(crate) struct UtxosQuery;
#[async_graphql::Object]
impl UtxosQuery {
    /// Utxos of script
    async fn utxos_of_script(
        &self,
        ctx: &async_graphql::Context<'_>,
        #[graphql(desc = "DUBP wallet script")] script: PkOrScriptGva,
        #[graphql(desc = "pagination", default)] pagination: Pagination,
        #[graphql(desc = "Amount needed")] amount: Option<i64>,
    ) -> async_graphql::Result<Connection<String, UtxoGva, AggregateSum, EmptyFields>> {
        let QueryContext { is_whitelisted } = ctx.data::<QueryContext>()?;
        log::info!("is_whitelisted={}", is_whitelisted);
        let pagination = Pagination::convert_to_page_info(pagination, *is_whitelisted)?;

        let data = ctx.data::<GvaSchemaData>()?;
        let db_reader = data.dbs_reader();

        let (
            PagedData {
                data: UtxosWithSum { utxos, sum },
                has_previous_page,
                has_next_page,
            },
            times,
        ) = data
            .dbs_pool
            .execute(move |dbs| {
                if let Some(current_block) = duniter_bc_reader::get_current_block_meta(&dbs.cm_db)?
                {
                    let paged_data = db_reader.find_script_utxos(
                        &dbs.txs_mp_db,
                        amount.map(|amount| {
                            SourceAmount::new(amount, current_block.unit_base as i64)
                        }),
                        pagination,
                        &script.0,
                    )?;
                    let mut times = Vec::with_capacity(paged_data.data.utxos.len());
                    for (UtxoCursor { block_number, .. }, _sa) in &paged_data.data.utxos {
                        times.push(db_reader.get_blockchain_time(*block_number)?);
                    }
                    Ok::<_, anyhow::Error>((paged_data, times))
                } else {
                    Err(anyhow::Error::msg("no blockchain"))
                }
            })
            .await??;

        let mut conn = Connection::with_additional_fields(
            has_previous_page,
            has_next_page,
            AggregateSum {
                aggregate: Sum {
                    sum: AmountWithBase {
                        amount: sum.amount() as i32,
                        base: sum.base() as i32,
                    },
                },
            },
        );
        conn.append(utxos.into_iter().zip(times.into_iter()).map(
            |((utxo_cursor, source_amount), blockchain_time)| {
                Edge::new(
                    utxo_cursor.to_string(),
                    UtxoGva {
                        amount: source_amount.amount(),
                        base: source_amount.base(),
                        tx_hash: utxo_cursor.tx_hash.to_hex(),
                        output_index: utxo_cursor.output_index as u32,
                        written_block: utxo_cursor.block_number.0,
                        written_time: blockchain_time,
                    },
                )
            },
        ));
        Ok(conn)
    }
}
<|endoftext|>


<commit_before>//! Utility functions for dealing with sRGB colors.
//!
//! The constant values in this module are taken from http://www.color.org/chardata/rgb/srgb.xalter
use std::slice;

use cairo;
use cairo::prelude::SurfaceExt;
use cairo_sys;

use filters::context::IRect;

/// Converts an sRGB color value to a linear sRGB color value (undoes the gamma correction).
///
/// The input and the output are supposed to be in the [0, 1] range.
#[inline]
pub fn linearize(c: f64) -> f64 {
    if c <= (12.92 * 0.0031308) {
        c / 12.92
    } else {
        ((c + 0.055) / 1.055).powf(2.4)
    }
}

/// Converts a linear sRGB color value to a normal sRGB color value (applies the gamma correction).
///
/// The input and the output are supposed to be in the [0, 1] range.
#[inline]
pub fn unlinearize(c: f64) -> f64 {
    if c <= 0.0031308 {
        12.92 * c
    } else {
        1.055 * c.powf(1f64 / 2.4) - 0.055
    }
}

/// Converts an sRGB surface to a linear sRGB surface (undoes the gamma correction).
///
/// The returned surface is transparent everywhere except the rectangle defined by `bounds`.
pub fn linearize_surface(
    surface: &cairo::ImageSurface,
    bounds: IRect,
) -> Result<cairo::ImageSurface, cairo::Status> {
    let width = surface.get_width();
    let height = surface.get_height();
    let input_stride = surface.get_stride();

    assert!(bounds.x0 >= 0);
    assert!(bounds.y0 >= 0);
    assert!(bounds.x1 < width);
    assert!(bounds.y1 < height);

    // TODO: this currently gives "non-exclusive access" (can we make read-only borrows?)
    // let input_data = surface.get_data().unwrap();
    surface.flush();
    if surface.status() != cairo::Status::Success {
        return Err(surface.status());
    }
    let input_data_ptr = unsafe { cairo_sys::cairo_image_surface_get_data(surface.to_raw_none()) };
    if input_data_ptr.is_null() {
        return Err(cairo::Status::SurfaceFinished);
    }
    let input_data_len = input_stride as usize * height as usize;
    let input_data = unsafe { slice::from_raw_parts(input_data_ptr, input_data_len) };

    let mut output_surface = cairo::ImageSurface::create(cairo::Format::ARgb32, width, height)?;
    let output_stride = output_surface.get_stride();

    {
        let mut output_data = output_surface.get_data().unwrap();

        for y in bounds.y0..bounds.y1 {
            for x in bounds.x0..bounds.x1 {
                let input_index = (y * input_stride + x * 4) as usize;
                let output_index = (y * output_stride + x * 4) as usize;

                let alpha = input_data[input_index + 3];

                if alpha > 0 {
                    let alpha = f64::from(alpha) / 255f64;

                    for c in 0..3 {
                        let input_value = f64::from(input_data[input_index + c]) / 255f64;
                        let input_value = input_value / alpha; // Unpremultiply alpha.

                        let output_value = linearize(input_value);
                        let output_value = output_value * alpha; // Premultiply alpha again.

                        output_data[output_index + c] = (output_value * 255f64).round() as u8;
                    }
                }

                output_data[output_index + 3] = alpha;
            }
        }
    }

    Ok(output_surface)
}

/// Converts a linear sRGB surface to a normal sRGB surface (applies the gamma correction).
///
/// The returned surface is transparent everywhere except the rectangle defined by `bounds`.
pub fn unlinearize_surface(
    surface: &cairo::ImageSurface,
    bounds: IRect,
) -> Result<cairo::ImageSurface, cairo::Status> {
    let width = surface.get_width();
    let height = surface.get_height();
    let input_stride = surface.get_stride();

    assert!(bounds.x0 >= 0);
    assert!(bounds.y0 >= 0);
    assert!(bounds.x1 < width);
    assert!(bounds.y1 < height);

    // TODO: this currently gives "non-exclusive access" (can we make read-only borrows?)
    // let input_data = surface.get_data().unwrap();
    surface.flush();
    if surface.status() != cairo::Status::Success {
        return Err(surface.status());
    }
    let input_data_ptr = unsafe { cairo_sys::cairo_image_surface_get_data(surface.to_raw_none()) };
    if input_data_ptr.is_null() {
        return Err(cairo::Status::SurfaceFinished);
    }
    let input_data_len = input_stride as usize * height as usize;
    let input_data = unsafe { slice::from_raw_parts(input_data_ptr, input_data_len) };

    let mut output_surface = cairo::ImageSurface::create(cairo::Format::ARgb32, width, height)?;
    let output_stride = output_surface.get_stride();

    {
        let mut output_data = output_surface.get_data().unwrap();

        for y in bounds.y0..bounds.y1 {
            for x in bounds.x0..bounds.x1 {
                let input_index = (y * input_stride + x * 4) as usize;
                let output_index = (y * output_stride + x * 4) as usize;

                let alpha = input_data[input_index + 3];

                if alpha > 0 {
                    let alpha = f64::from(alpha) / 255f64;

                    for c in 0..3 {
                        let input_value = f64::from(input_data[input_index + c]) / 255f64;
                        let input_value = input_value / alpha; // Unpremultiply alpha.

                        let output_value = unlinearize(input_value);
                        let output_value = output_value * alpha; // Premultiply alpha again.

                        output_data[output_index + c] = (output_value * 255f64).round() as u8;
                    }
                }

                output_data[output_index + 3] = alpha;
            }
        }
    }

    Ok(output_surface)
}
<commit_msg>Fix invalid assert conditions in srgb<commit_after>//! Utility functions for dealing with sRGB colors.
//!
//! The constant values in this module are taken from http://www.color.org/chardata/rgb/srgb.xalter
use std::slice;

use cairo;
use cairo::prelude::SurfaceExt;
use cairo_sys;

use filters::context::IRect;

/// Converts an sRGB color value to a linear sRGB color value (undoes the gamma correction).
///
/// The input and the output are supposed to be in the [0, 1] range.
#[inline]
pub fn linearize(c: f64) -> f64 {
    if c <= (12.92 * 0.0031308) {
        c / 12.92
    } else {
        ((c + 0.055) / 1.055).powf(2.4)
    }
}

/// Converts a linear sRGB color value to a normal sRGB color value (applies the gamma correction).
///
/// The input and the output are supposed to be in the [0, 1] range.
#[inline]
pub fn unlinearize(c: f64) -> f64 {
    if c <= 0.0031308 {
        12.92 * c
    } else {
        1.055 * c.powf(1f64 / 2.4) - 0.055
    }
}

/// Converts an sRGB surface to a linear sRGB surface (undoes the gamma correction).
///
/// The returned surface is transparent everywhere except the rectangle defined by `bounds`.
pub fn linearize_surface(
    surface: &cairo::ImageSurface,
    bounds: IRect,
) -> Result<cairo::ImageSurface, cairo::Status> {
    let width = surface.get_width();
    let height = surface.get_height();
    let input_stride = surface.get_stride();

    assert!(bounds.x0 >= 0);
    assert!(bounds.y0 >= 0);
    assert!(bounds.x1 <= width);
    assert!(bounds.y1 <= height);

    // TODO: this currently gives "non-exclusive access" (can we make read-only borrows?)
    // let input_data = surface.get_data().unwrap();
    surface.flush();
    if surface.status() != cairo::Status::Success {
        return Err(surface.status());
    }
    let input_data_ptr = unsafe { cairo_sys::cairo_image_surface_get_data(surface.to_raw_none()) };
    if input_data_ptr.is_null() {
        return Err(cairo::Status::SurfaceFinished);
    }
    let input_data_len = input_stride as usize * height as usize;
    let input_data = unsafe { slice::from_raw_parts(input_data_ptr, input_data_len) };

    let mut output_surface = cairo::ImageSurface::create(cairo::Format::ARgb32, width, height)?;
    let output_stride = output_surface.get_stride();

    {
        let mut output_data = output_surface.get_data().unwrap();

        for y in bounds.y0..bounds.y1 {
            for x in bounds.x0..bounds.x1 {
                let input_index = (y * input_stride + x * 4) as usize;
                let output_index = (y * output_stride + x * 4) as usize;

                let alpha = input_data[input_index + 3];

                if alpha > 0 {
                    let alpha = f64::from(alpha) / 255f64;

                    for c in 0..3 {
                        let input_value = f64::from(input_data[input_index + c]) / 255f64;
                        let input_value = input_value / alpha; // Unpremultiply alpha.

                        let output_value = linearize(input_value);
                        let output_value = output_value * alpha; // Premultiply alpha again.

                        output_data[output_index + c] = (output_value * 255f64).round() as u8;
                    }
                }

                output_data[output_index + 3] = alpha;
            }
        }
    }

    Ok(output_surface)
}

/// Converts a linear sRGB surface to a normal sRGB surface (applies the gamma correction).
///
/// The returned surface is transparent everywhere except the rectangle defined by `bounds`.
pub fn unlinearize_surface(
    surface: &cairo::ImageSurface,
    bounds: IRect,
) -> Result<cairo::ImageSurface, cairo::Status> {
    let width = surface.get_width();
    let height = surface.get_height();
    let input_stride = surface.get_stride();

    assert!(bounds.x0 >= 0);
    assert!(bounds.y0 >= 0);
    assert!(bounds.x1 <= width);
    assert!(bounds.y1 <= height);

    // TODO: this currently gives "non-exclusive access" (can we make read-only borrows?)
    // let input_data = surface.get_data().unwrap();
    surface.flush();
    if surface.status() != cairo::Status::Success {
        return Err(surface.status());
    }
    let input_data_ptr = unsafe { cairo_sys::cairo_image_surface_get_data(surface.to_raw_none()) };
    if input_data_ptr.is_null() {
        return Err(cairo::Status::SurfaceFinished);
    }
    let input_data_len = input_stride as usize * height as usize;
    let input_data = unsafe { slice::from_raw_parts(input_data_ptr, input_data_len) };

    let mut output_surface = cairo::ImageSurface::create(cairo::Format::ARgb32, width, height)?;
    let output_stride = output_surface.get_stride();

    {
        let mut output_data = output_surface.get_data().unwrap();

        for y in bounds.y0..bounds.y1 {
            for x in bounds.x0..bounds.x1 {
                let input_index = (y * input_stride + x * 4) as usize;
                let output_index = (y * output_stride + x * 4) as usize;

                let alpha = input_data[input_index + 3];

                if alpha > 0 {
                    let alpha = f64::from(alpha) / 255f64;

                    for c in 0..3 {
                        let input_value = f64::from(input_data[input_index + c]) / 255f64;
                        let input_value = input_value / alpha; // Unpremultiply alpha.

                        let output_value = unlinearize(input_value);
                        let output_value = output_value * alpha; // Premultiply alpha again.

                        output_data[output_index + c] = (output_value * 255f64).round() as u8;
                    }
                }

                output_data[output_index + 3] = alpha;
            }
        }
    }

    Ok(output_surface)
}
<|endoftext|>