<commit_before>extern crate cargo_update;
extern crate tabwriter;

use std::io::{Write, stdout};
use tabwriter::TabWriter;
use std::process::exit;

fn main() {
    let result = actual_main().err().unwrap_or(0);
    exit(result);
}

fn actual_main() -> Result<(), i32> {
    let opts = cargo_update::ConfigOptions::parse();
    let config_file = cargo_update::ops::resolve_crates_file(opts.crates_file.1).with_file_name(".install_config.toml");

    let mut configuration = cargo_update::ops::PackageConfig::read(&config_file).map_err(|(e, r)| {
            eprintln!("Reading config: {}", e);
            r
        })?;
    if !opts.ops.is_empty() {
        let mut changed = false;
        if let Some(ref mut cfg) = configuration.get_mut(&opts.package) {
            cfg.execute_operations(&opts.ops);
            changed = true;
            if **cfg == Default::default() {
                configuration.remove(&opts.package);
            }
        }
        if !changed {
            configuration.insert(opts.package.clone(), cargo_update::ops::PackageConfig::from(&opts.ops));
        }

        cargo_update::ops::PackageConfig::write(&configuration, &config_file).map_err(|(e, r)| {
            eprintln!("Writing config: {}", e);
            r
        })?;
    }

    if let Some(cfg) = configuration.get(&opts.package) {
        let mut out = TabWriter::new(stdout());
        if let Some(ref t) = cfg.toolchain {
            writeln!(out, "Toolchain\t{}", t).unwrap();
        }
        if let Some(d) = cfg.debug {
            writeln!(out, "Debug mode\t{}", d).unwrap();
        }
        if let Some(ip) = cfg.install_prereleases {
            writeln!(out, "Install prereleases\t{}", ip).unwrap();
        }
        if let Some(el) = cfg.enforce_lock {
            writeln!(out, "Enforce lock\t{}", el).unwrap();
        }
        if let Some(rb) = cfg.respect_binaries {
            writeln!(out, "Respect binaries\t{}", rb).unwrap();
        }
        if let Some(ref tv) = cfg.target_version {
            writeln!(out, "Target version\t{}", tv).unwrap();
        }
        writeln!(out, "Default features\t{}", cfg.default_features).unwrap();
        if !cfg.features.is_empty() {
            write!(out, "Features").unwrap();
            for f in &cfg.features {
                writeln!(out, "\t{}", f).unwrap();
            }
        }
        out.flush().unwrap();
    } else {
        println!("No configuration for package {}.", opts.package);
    }

    Ok(())
}
<commit_msg>Oh, NLL, I love you so<commit_after>extern crate cargo_update;
extern crate tabwriter;

use std::io::{Write, stdout};
use tabwriter::TabWriter;
use std::process::exit;

fn main() {
    let result = actual_main().err().unwrap_or(0);
    exit(result);
}

fn actual_main() -> Result<(), i32> {
    let opts = cargo_update::ConfigOptions::parse();
    let config_file = cargo_update::ops::resolve_crates_file(opts.crates_file.1).with_file_name(".install_config.toml");

    let mut configuration = cargo_update::ops::PackageConfig::read(&config_file).map_err(|(e, r)| {
            eprintln!("Reading config: {}", e);
            r
        })?;
    if !opts.ops.is_empty() {
        let mut changed = false;
        if let Some(ref mut cfg) = configuration.get_mut(&opts.package) {
            cfg.execute_operations(&opts.ops);
            changed = true;
        }
        if !changed {
            configuration.insert(opts.package.clone(), cargo_update::ops::PackageConfig::from(&opts.ops));
        }
        if *configuration.get(&opts.package).unwrap() == Default::default() {
            configuration.remove(&opts.package);
        }

        cargo_update::ops::PackageConfig::write(&configuration, &config_file).map_err(|(e, r)| {
                eprintln!("Writing config: {}", e);
                r
            })?;
    }

    if let Some(cfg) = configuration.get(&opts.package) {
        let mut out = TabWriter::new(stdout());
        if let Some(ref t) = cfg.toolchain {
            writeln!(out, "Toolchain\t{}", t).unwrap();
        }
        if let Some(d) = cfg.debug {
            writeln!(out, "Debug mode\t{}", d).unwrap();
        }
        if let Some(ip) = cfg.install_prereleases {
            writeln!(out, "Install prereleases\t{}", ip).unwrap();
        }
        if let Some(el) = cfg.enforce_lock {
            writeln!(out, "Enforce lock\t{}", el).unwrap();
        }
        if let Some(rb) = cfg.respect_binaries {
            writeln!(out, "Respect binaries\t{}", rb).unwrap();
        }
        if let Some(ref tv) = cfg.target_version {
            writeln!(out, "Target version\t{}", tv).unwrap();
        }
        writeln!(out, "Default features\t{}", cfg.default_features).unwrap();
        if !cfg.features.is_empty() {
            write!(out, "Features").unwrap();
            for f in &cfg.features {
                writeln!(out, "\t{}", f).unwrap();
            }
        }
        out.flush().unwrap();
    } else {
        println!("No configuration for package {}.", opts.package);
    }

    Ok(())
}
<|endoftext|>


<commit_before>extern crate rand;

use rand::random;
use std::io::BufferedReader;
use std::io;

fn main() {
    println!("I'm thinking of a number between 1 and 100. Can you guess it?");
    let x = random::<int>();
    let mut reader = BufferedReader::new(io::stdin());
    while true {
        let line_result = reader.read_line();
        if line_result.is_ok() {
            let line = line_result.unwrap();
            let num = from_str::<int>(line.slice_to(line.len() - 1));
            match num {
                Some(x) => break,
                Some(_number_string) => println!("Well, it was a number."),
                None                 => println!("Doesn't count.")
            }
        }
        else {
            println!("An error occurred.");
            break;
        }
    }
}
<commit_msg>This syntax is correct. Lots to analyze, I think.<commit_after>extern crate rand;

use rand::random;
use std::io::BufferedReader;
use std::io;

fn main() {
    println!("I'm thinking of a number between 1 and 100. Can you guess it?");
    let x = random::<int>();
    let mut reader = BufferedReader::new(io::stdin());
    while true {
        let line_result = reader.read_line();
        if line_result.is_ok() {
            let line = line_result.unwrap();
            let num = from_str::<int>(line.slice_to(line.len() - 1));
            match num {
                Some(number_string) => if number_string == x {println!("Right!"); break;} else {println!("Wrong!")},
                None                => println!("Doesn't count.")
            }
        }
        else {
            println!("An error occurred.");
            break;
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2015-2017 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! An LRU cache designed for work with DNS lookups

use std::sync::Arc;
use std::time::{Duration, Instant};

use trust_dns_proto::op::Query;
use trust_dns_proto::rr::RData;

use error::*;
use lookup::Lookup;
use lru_cache::LruCache;

/// Maximum TTL as defined in https://tools.ietf.org/html/rfc2181
pub const MAX_TTL: u32 = 2147483647_u32;

#[derive(Debug)]
struct LruValue {
    // In the None case, this represents an NXDomain
    lookup: Option<Lookup>,
    ttl_until: Instant,
}

impl LruValue {
    /// Returns true if this set of ips is still valid
    fn is_current(&self, now: Instant) -> bool {
        now <= self.ttl_until
    }
}

#[derive(Debug)]
pub(crate) struct DnsLru(LruCache<Query, LruValue>);

impl DnsLru {
    pub(crate) fn new(capacity: usize) -> Self {
        DnsLru(LruCache::new(capacity))
    }

    pub(crate) fn insert(
        &mut self,
        query: Query,
        rdatas_and_ttl: Vec<(RData, u32)>,
        now: Instant,
    ) -> Lookup {
        let len = rdatas_and_ttl.len();
        // collapse the values, we're going to take the Minimum TTL as the correct one
        let (rdatas, ttl): (Vec<RData>, u32) = rdatas_and_ttl.into_iter().fold(
            (Vec::with_capacity(len), MAX_TTL),
            |(mut rdatas, mut min_ttl), (rdata, ttl)| {
                rdatas.push(rdata);
                min_ttl = min_ttl.min(ttl);
                (rdatas, min_ttl)
            },
        );

        let ttl = Duration::from_secs(ttl as u64);
        let ttl_until = now + ttl;

        // insert into the LRU
        let lookup = Lookup::new_with_deadline(Arc::new(rdatas), ttl_until);
        self.0.insert(
            query,
            LruValue {
                lookup: Some(lookup.clone()),
                ttl_until,
            },
        );

        lookup
    }

    /// Generally for inserting a set of records that have already been cached, but with a different Query.
    pub(crate) fn duplicate(
        &mut self,
        query: Query,
        lookup: Lookup,
        ttl: u32,
        now: Instant,
    ) -> Lookup {
        let ttl = Duration::from_secs(ttl as u64);
        let ttl_until = now + ttl;

        self.0.insert(
            query,
            LruValue {
                lookup: Some(lookup.clone()),
                ttl_until,
            },
        );

        lookup
    }

    pub(crate) fn nx_error(query: Query) -> ResolveError {
        ResolveErrorKind::NoRecordsFound(query).into()
    }

    pub(crate) fn negative(&mut self, query: Query, ttl: u32, now: Instant) -> ResolveError {
        // TODO: if we are getting a negative response, should we instead fallback to cache?
        //   this would cache indefinitely, probably not correct

        let ttl = Duration::from_secs(ttl as u64);
        let ttl_until = now + ttl;

        self.0.insert(
            query.clone(),
            LruValue {
                lookup: None,
                ttl_until,
            },
        );

        Self::nx_error(query)
    }

    /// This needs to be mut b/c it's an LRU, meaning the ordering of elements will potentially change on retrieval...
    pub(crate) fn get(&mut self, query: &Query, now: Instant) -> Option<Lookup> {
        let mut out_of_date = false;
        let lookup = self.0.get_mut(query).and_then(|value| {
            if value.is_current(now) {
                out_of_date = false;
                value.lookup.clone()
            } else {
                out_of_date = true;
                None
            }
        });

        // in this case, we can preemtively remove out of data elements
        // this assumes time is always moving forward, this would only not be true in contrived situations where now
        //  is not current time, like tests...
        if out_of_date {
            self.0.remove(query);
        }

        lookup
    }
}

// see also the lookup_tests.rs in integration-tests crate
#[cfg(test)]
mod tests {
    use std::net::*;
    use std::str::FromStr;
    use std::time::*;

    use trust_dns_proto::op::Query;
    use trust_dns_proto::rr::{Name, RecordType};

    use super::*;

    #[test]
    fn test_is_current() {
        let now = Instant::now();
        let not_the_future = now + Duration::from_secs(4);
        let future = now + Duration::from_secs(5);
        let past_the_future = now + Duration::from_secs(6);

        let value = LruValue {
            lookup: None,
            ttl_until: future,
        };

        assert!(value.is_current(now));
        assert!(value.is_current(not_the_future));
        assert!(value.is_current(future));
        assert!(!value.is_current(past_the_future));
    }

    #[test]
    fn test_insert() {
        let now = Instant::now();
        let name = Query::query(Name::from_str("www.example.com.").unwrap(), RecordType::A);
        let ips_ttl = vec![(RData::A(Ipv4Addr::new(127, 0, 0, 1)), 1)];
        let ips = vec![RData::A(Ipv4Addr::new(127, 0, 0, 1))];
        let mut lru = DnsLru::new(1);

        let rc_ips = lru.insert(name.clone(), ips_ttl, now);
        assert_eq!(*rc_ips.iter().next().unwrap(), ips[0]);

        let rc_ips = lru.get(&name, now).unwrap();
        assert_eq!(*rc_ips.iter().next().unwrap(), ips[0]);
    }

    #[test]
    fn test_insert_ttl() {
        let now = Instant::now();
        let name = Query::query(Name::from_str("www.example.com.").unwrap(), RecordType::A);
        // TTL should be 1
        let ips_ttl = vec![
            (RData::A(Ipv4Addr::new(127, 0, 0, 1)), 1),
            (RData::A(Ipv4Addr::new(127, 0, 0, 2)), 2),
        ];
        let ips = vec![
            RData::A(Ipv4Addr::new(127, 0, 0, 1)),
            RData::A(Ipv4Addr::new(127, 0, 0, 2)),
        ];
        let mut lru = DnsLru::new(1);

        lru.insert(name.clone(), ips_ttl, now);

        // still valid
        let rc_ips = lru.get(&name, now + Duration::from_secs(1)).unwrap();
        assert_eq!(*rc_ips.iter().next().unwrap(), ips[0]);

        // 2 should be one too far
        let rc_ips = lru.get(&name, now + Duration::from_secs(2));
        assert!(rc_ips.is_none());
    }
}
<commit_msg>resolver: rename LruValue.ttl_until for consistency<commit_after>// Copyright 2015-2017 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! An LRU cache designed for work with DNS lookups

use std::sync::Arc;
use std::time::{Duration, Instant};

use trust_dns_proto::op::Query;
use trust_dns_proto::rr::RData;

use error::*;
use lookup::Lookup;
use lru_cache::LruCache;

/// Maximum TTL as defined in https://tools.ietf.org/html/rfc2181
pub const MAX_TTL: u32 = 2147483647_u32;

#[derive(Debug)]
struct LruValue {
    // In the None case, this represents an NXDomain
    lookup: Option<Lookup>,
    valid_until: Instant,
}

impl LruValue {
    /// Returns true if this set of ips is still valid
    fn is_current(&self, now: Instant) -> bool {
        now <= self.valid_until
    }
}

#[derive(Debug)]
pub(crate) struct DnsLru(LruCache<Query, LruValue>);

impl DnsLru {
    pub(crate) fn new(capacity: usize) -> Self {
        DnsLru(LruCache::new(capacity))
    }

    pub(crate) fn insert(
        &mut self,
        query: Query,
        rdatas_and_ttl: Vec<(RData, u32)>,
        now: Instant,
    ) -> Lookup {
        let len = rdatas_and_ttl.len();
        // collapse the values, we're going to take the Minimum TTL as the correct one
        let (rdatas, ttl): (Vec<RData>, u32) = rdatas_and_ttl.into_iter().fold(
            (Vec::with_capacity(len), MAX_TTL),
            |(mut rdatas, mut min_ttl), (rdata, ttl)| {
                rdatas.push(rdata);
                min_ttl = min_ttl.min(ttl);
                (rdatas, min_ttl)
            },
        );

        let ttl = Duration::from_secs(ttl as u64);
        let valid_until = now + ttl;

        // insert into the LRU
        let lookup = Lookup::new_with_deadline(Arc::new(rdatas), valid_until);
        self.0.insert(
            query,
            LruValue {
                lookup: Some(lookup.clone()),
                valid_until,
            },
        );

        lookup
    }

    /// Generally for inserting a set of records that have already been cached, but with a different Query.
    pub(crate) fn duplicate(
        &mut self,
        query: Query,
        lookup: Lookup,
        ttl: u32,
        now: Instant,
    ) -> Lookup {
        let ttl = Duration::from_secs(ttl as u64);
        let valid_until = now + ttl;

        self.0.insert(
            query,
            LruValue {
                lookup: Some(lookup.clone()),
                valid_until,
            },
        );

        lookup
    }

    pub(crate) fn nx_error(query: Query) -> ResolveError {
        ResolveErrorKind::NoRecordsFound(query).into()
    }

    pub(crate) fn negative(&mut self, query: Query, ttl: u32, now: Instant) -> ResolveError {
        // TODO: if we are getting a negative response, should we instead fallback to cache?
        //   this would cache indefinitely, probably not correct

        let ttl = Duration::from_secs(ttl as u64);
        let valid_until = now + ttl;

        self.0.insert(
            query.clone(),
            LruValue {
                lookup: None,
                valid_until,
            },
        );

        Self::nx_error(query)
    }

    /// This needs to be mut b/c it's an LRU, meaning the ordering of elements will potentially change on retrieval...
    pub(crate) fn get(&mut self, query: &Query, now: Instant) -> Option<Lookup> {
        let mut out_of_date = false;
        let lookup = self.0.get_mut(query).and_then(|value| {
            if value.is_current(now) {
                out_of_date = false;
                value.lookup.clone()
            } else {
                out_of_date = true;
                None
            }
        });

        // in this case, we can preemtively remove out of data elements
        // this assumes time is always moving forward, this would only not be true in contrived situations where now
        //  is not current time, like tests...
        if out_of_date {
            self.0.remove(query);
        }

        lookup
    }
}

// see also the lookup_tests.rs in integration-tests crate
#[cfg(test)]
mod tests {
    use std::net::*;
    use std::str::FromStr;
    use std::time::*;

    use trust_dns_proto::op::Query;
    use trust_dns_proto::rr::{Name, RecordType};

    use super::*;

    #[test]
    fn test_is_current() {
        let now = Instant::now();
        let not_the_future = now + Duration::from_secs(4);
        let future = now + Duration::from_secs(5);
        let past_the_future = now + Duration::from_secs(6);

        let value = LruValue {
            lookup: None,
            valid_until: future,
        };

        assert!(value.is_current(now));
        assert!(value.is_current(not_the_future));
        assert!(value.is_current(future));
        assert!(!value.is_current(past_the_future));
    }

    #[test]
    fn test_insert() {
        let now = Instant::now();
        let name = Query::query(Name::from_str("www.example.com.").unwrap(), RecordType::A);
        let ips_ttl = vec![(RData::A(Ipv4Addr::new(127, 0, 0, 1)), 1)];
        let ips = vec![RData::A(Ipv4Addr::new(127, 0, 0, 1))];
        let mut lru = DnsLru::new(1);

        let rc_ips = lru.insert(name.clone(), ips_ttl, now);
        assert_eq!(*rc_ips.iter().next().unwrap(), ips[0]);

        let rc_ips = lru.get(&name, now).unwrap();
        assert_eq!(*rc_ips.iter().next().unwrap(), ips[0]);
    }

    #[test]
    fn test_insert_ttl() {
        let now = Instant::now();
        let name = Query::query(Name::from_str("www.example.com.").unwrap(), RecordType::A);
        // TTL should be 1
        let ips_ttl = vec![
            (RData::A(Ipv4Addr::new(127, 0, 0, 1)), 1),
            (RData::A(Ipv4Addr::new(127, 0, 0, 2)), 2),
        ];
        let ips = vec![
            RData::A(Ipv4Addr::new(127, 0, 0, 1)),
            RData::A(Ipv4Addr::new(127, 0, 0, 2)),
        ];
        let mut lru = DnsLru::new(1);

        lru.insert(name.clone(), ips_ttl, now);

        // still valid
        let rc_ips = lru.get(&name, now + Duration::from_secs(1)).unwrap();
        assert_eq!(*rc_ips.iter().next().unwrap(), ips[0]);

        // 2 should be one too far
        let rc_ips = lru.get(&name, now + Duration::from_secs(2));
        assert!(rc_ips.is_none());
    }
}
<|endoftext|>


<commit_before>#![feature(phase,globs)]
#![feature(macro_rules)]
#![feature(trace_macros, concat_idents)]

#[phase(syntax, link)]
extern crate log;
extern crate rand;
extern crate serialize;
extern crate collections;
extern crate sync;
extern crate uuid;

extern crate regex;
#[phase(syntax)] extern crate regex_macros;

use std::comm::Select;
// use std::comm::{Empty, Data, Disconnected};
use std::{cmp};
use std::vec::Vec;
use std::io::Timer;

// TODO: None of this should be in this module. It should go into net
// (I believe they are all to do with communicating with Peers)
use std::io::IoResult;
use rand::{task_rng,Rng};
use sync::TaskPool;

use self::consistent_log::{Log,LogEntry};
use self::net::*;
use events::{ClientCmdReq, ClientCmdRes};
use self::events::append_entries::{AppendEntriesReq,AppendEntriesRes};
use self::server::RaftServer;

mod events;
mod consistent_log;
mod net;

mod server;
mod leader;
mod candidate;
mod follower;

fn main() {
    let (endp_send, endp_recv): (Sender<(ClientCmdReq, Sender<ClientCmdRes>)>,
                                 Receiver<(ClientCmdReq, Sender<ClientCmdRes>)>) = channel();
    let (sm_send, sm_recv): (Sender<(ClientCmdReq, Sender<ClientCmdRes>)>,
                             Receiver<(ClientCmdReq, Sender<ClientCmdRes>)>) = channel();
    spawn(proc() {
        // Stupid dummy state machine
        loop {
            sm_recv.recv();
        }
    });
    let mut server = RaftServer::new();
    server.spawn(sm_send, endp_recv);
}
<commit_msg>Suppress some warnings for the moment<commit_after>#![feature(phase,globs)]
#![feature(macro_rules)]
#![feature(trace_macros, concat_idents)]

// We're Cutting Edge
#![allow(experimental)]

// This suppresses lots of warnings, which means we ignore less of
// them. TODO: Remove this line.
#![allow(dead_code,unused_imports,unused_variable,unused_mut,unnecessary_parens)]

#[phase(syntax, link)]
extern crate log;
extern crate rand;
extern crate serialize;
extern crate collections;
extern crate sync;
extern crate uuid;

extern crate regex;
#[phase(syntax)] extern crate regex_macros;

use std::comm::Select;
// use std::comm::{Empty, Data, Disconnected};
use std::{cmp};
use std::vec::Vec;
use std::io::Timer;

// TODO: None of this should be in this module. It should go into net
// (I believe they are all to do with communicating with Peers)
use std::io::IoResult;
use rand::{task_rng,Rng};
use sync::TaskPool;

use self::consistent_log::{Log,LogEntry};
use self::net::*;
use events::{ClientCmdReq, ClientCmdRes};
use self::events::append_entries::{AppendEntriesReq,AppendEntriesRes};
use self::server::RaftServer;

mod events;
mod consistent_log;
mod net;

mod server;
mod leader;
mod candidate;
mod follower;

fn main() {
    let (endp_send, endp_recv): (Sender<(ClientCmdReq, Sender<ClientCmdRes>)>,
                                 Receiver<(ClientCmdReq, Sender<ClientCmdRes>)>) = channel();
    let (sm_send, sm_recv): (Sender<(ClientCmdReq, Sender<ClientCmdRes>)>,
                             Receiver<(ClientCmdReq, Sender<ClientCmdRes>)>) = channel();
    spawn(proc() {
        // Stupid dummy state machine
        loop {
            sm_recv.recv();
        }
    });
    let mut server = RaftServer::new();
    server.spawn(sm_send, endp_recv);
}
<|endoftext|>


<commit_before>// run-pass

#![allow(irrefutable_let_patterns)]

#[allow(dead_code)]
enum Enum<T> { TSVariant(T), SVariant { v: T } }
type Alias<T> = Enum<T>;
type AliasFixed = Enum<()>;

macro_rules! is_variant {
    (TSVariant, $expr:expr) => (is_variant!(@check TSVariant, (_), $expr));
    (SVariant, $expr:expr) => (is_variant!(@check SVariant, { v: _ }, $expr));
    (@check $variant:ident, $matcher:tt, $expr:expr) => (
        assert!(if let Enum::$variant::<()> $matcher = $expr { true } else { false },
                "expr does not have correct type");
    );
}

fn main() {
    // Tuple struct variant

    is_variant!(TSVariant, Enum::TSVariant(()));
    is_variant!(TSVariant, Enum::TSVariant::<()>(()));
    is_variant!(TSVariant, Enum::<()>::TSVariant(()));

    is_variant!(TSVariant, Alias::TSVariant(()));
    is_variant!(TSVariant, Alias::<()>::TSVariant(()));

    is_variant!(TSVariant, AliasFixed::TSVariant(()));

    // Struct variant

    is_variant!(SVariant, Enum::SVariant { v: () });
    is_variant!(SVariant, Enum::SVariant::<()> { v: () });
    is_variant!(SVariant, Enum::<()>::SVariant { v: () });

    is_variant!(SVariant, Alias::SVariant { v: () });
    is_variant!(SVariant, Alias::<()>::SVariant { v: () });

    is_variant!(SVariant, AliasFixed::SVariant { v: () });
}
<commit_msg>enum-variant-generic-args-pats-pass: harden + describe.<commit_after>// run-pass

// Check that resolving, in the value namespace, to an `enum` variant
// through a type alias is well behaved in the presence of generics.
// We check for situations with:
// 1. a generic type `Alias<T>`, we can type-apply `Alias` when referring to a variant.
// 2. a monotype `AliasFixed` of generic `Enum<T>`, we can refer to variants
//    and the type-application of `T` in `AliasFixed` is kept.

#![allow(irrefutable_let_patterns)]

#[allow(dead_code)]
enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
type Alias<T> = Enum<T>;
type AliasFixed = Enum<()>;

macro_rules! is_variant {
    (TSVariant, $expr:expr) => (is_variant!(@check TSVariant, (_), $expr));
    (SVariant, $expr:expr) => (is_variant!(@check SVariant, { v: _ }, $expr));
    (UVariant, $expr:expr) => (is_variant!(@check UVariant, {}, $expr));
    (@check $variant:ident, $matcher:tt, $expr:expr) => (
        assert!(if let Enum::$variant::<()> $matcher = $expr { true } else { false },
                "expr does not have correct type");
    );
}

fn main() {
    // Tuple struct variant

    is_variant!(TSVariant, Enum::TSVariant(()));
    is_variant!(TSVariant, Enum::TSVariant::<()>(()));
    is_variant!(TSVariant, Enum::<()>::TSVariant(()));

    is_variant!(TSVariant, Alias::TSVariant(()));
    is_variant!(TSVariant, Alias::<()>::TSVariant(()));

    is_variant!(TSVariant, AliasFixed::TSVariant(()));

    // Struct variant

    is_variant!(SVariant, Enum::SVariant { v: () });
    is_variant!(SVariant, Enum::SVariant::<()> { v: () });
    is_variant!(SVariant, Enum::<()>::SVariant { v: () });

    is_variant!(SVariant, Alias::SVariant { v: () });
    is_variant!(SVariant, Alias::<()>::SVariant { v: () });

    is_variant!(SVariant, AliasFixed::SVariant { v: () });

    // Unit variant

    is_variant!(UVariant, Enum::UVariant);
    is_variant!(UVariant, Enum::UVariant::<()>);
    is_variant!(UVariant, Enum::<()>::UVariant);

    is_variant!(UVariant, Alias::UVariant);
    is_variant!(UVariant, Alias::<()>::UVariant);

    is_variant!(UVariant, AliasFixed::UVariant);
}
<|endoftext|>


<commit_before>use std::{mem, sync::Arc};

use bifrost::{conshash::ConsistentHashing, raft::client::RaftClient, rpc::RPCError};
use dovahkiin::{expr::serde::Expr, types::OwnedValue};
use futures::stream::{FuturesUnordered, StreamExt};
use itertools::Itertools;

use crate::{
    client::{client_by_server_id, client_by_server_name},
    index::{
        ranged::{client::cursor::ClientCursor, lsm::btree::Ordering},
        EntryKey, IndexerClients, SCHEMA_SCAN_PATT_SIZE,
    },
    ram::cell::{OwnedCell, ReadError},
};

const SCAN_BUFFER_SIZE: u16 = 64;

pub struct IndexedDataClient {
    conshash: Arc<ConsistentHashing>,
    index_clients: Arc<IndexerClients>,
}

pub struct DataCursor<'a> {
    index_cursor: Option<ClientCursor>,
    buffer: Vec<OwnedCell>,
    projection: Vec<u64>,
    selection: Expr,
    proc: Expr,
    client: &'a IndexedDataClient,
    pos: usize,
}

impl IndexedDataClient {
    pub fn new(conshash: &Arc<ConsistentHashing>, raft_client: &Arc<RaftClient>) -> Self {
        Self {
            conshash: conshash.clone(),
            index_clients: Arc::new(IndexerClients::new(conshash, raft_client)),
        }
    }
    pub async fn range_index_scan<'a>(
        &self,
        schema: u32,
        field: u64,
        key: u64,
        selection: OwnedValue,
        projection: OwnedValue,
    ) -> DataCursor<'a> {
        unimplemented!()
    }
    pub async fn scan_all<'a>(
        &'a self,
        schema: u32,
        projection: Vec<u64>, // Column array
        selection: Expr,      // Checker expression
        proc: Expr,
        ordering: Ordering,
    ) -> Result<DataCursor<'a>, RPCError> {
        let key = EntryKey::for_schema(schema);
        let index_cursor = self
            .index_clients
            .range_seek(
                &key,
                ordering,
                SCAN_BUFFER_SIZE,
                Some(SCHEMA_SCAN_PATT_SIZE),
            )
            .await?;
        let mut cursor = DataCursor {
            index_cursor,
            projection,
            selection,
            proc,
            client: self,
            buffer: vec![],
            pos: 0,
        };
        cursor.refresh_batch().await;
        Ok(cursor)
    }
}

impl<'a> DataCursor<'a> {
    pub async fn next(&mut self) -> Result<Option<OwnedCell>, RPCError> {
        if self.buffer.len() <= self.pos {
            if self.next_block().await? {
                if !self.refresh_batch().await {
                    return Ok(None);
                }
            } else {
                return Ok(None);
            }
        }
        if self.buffer.is_empty() {
            return Ok(None);
        }
        let cell = mem::take(&mut self.buffer[self.pos]);
        self.pos += 1;
        return Ok(Some(cell));
    }

    pub async fn next_block(&mut self) -> Result<bool, RPCError> {
        if let Some(cursor) = &mut self.index_cursor {
            if cursor.next_block().await? {
                return Ok(true);
            }
        }
        // If cannot get next block, set the index cursor to none
        // We are done with this cursor
        self.index_cursor = None;
        self.buffer = vec![];
        self.pos = 0;
        return Ok(false);
    }

    pub async fn refresh_batch(&mut self) -> bool {
        if let Some(cursor) = &self.index_cursor {
            let all_ids = cursor.current_block();
            let mut tasks = all_ids
                .iter()
                .enumerate()
                .filter_map(|(i, id)| {
                    self.client
                        .conshash
                        .get_server_id_by(id)
                        .map(|sid| (i, sid, id))
                })
                .group_by(|(_i, sid, _id)| *sid)
                .into_iter()
                .map(|(sid, pairs)| {
                    let mut ids = vec![];
                    let mut idx = vec![];
                    for (i, _, id) in pairs {
                        idx.push(i);
                        ids.push(*id);
                    }
                    let projection = self.projection.clone();
                    let selection = self.selection.clone();
                    let proc = self.proc.clone();
                    let server_name = self.client.conshash.to_server_name(sid);
                    async move {
                        match client_by_server_name(sid, server_name).await {
                            Ok(client) => {
                                let read_res = client
                                    .read_all_cells_proced(ids, projection, selection, proc)
                                    .await
                                    .map(|v| v.into_iter().zip(idx).collect_vec());
                                match read_res {
                                    Ok(cells) => Ok(cells
                                        .into_iter()
                                        .filter_map(|(c, i)| c.ok().map(|c| (c, i)))
                                        .collect_vec()),
                                    Err(e) => return Err(e),
                                }
                            }
                            Err(e) => return Err(e),
                        }
                    }
                })
                .collect::<FuturesUnordered<_>>();
            let mut all_cells = vec![];
            while let Some(task_res) = tasks.next().await {
                if let Ok(mut cells) = task_res {
                    all_cells.append(&mut cells);
                }
            }
            all_cells.sort_by(|(_, i1), (_, i2)| i1.cmp(i2));
            self.buffer = all_cells.into_iter().map(|(c, _)| c).collect_vec();
            self.pos = 0;
            true
        } else {
            self.buffer = vec![];
            self.pos = 0;
            false
        }
    }
}

#[cfg(test)]
mod test {
    use crate::{
        index::ranged::lsm::btree::Ordering,
        ram::{
            cell::OwnedCell,
            schema::{Field, IndexType, Schema},
        },
        server::*,
    };
    use bifrost_hasher::hash_str;
    use dovahkiin::{expr::serde::Expr, types::*, integrated::lisp::*};

    #[tokio::test(flavor = "multi_thread")]
    async fn scan_all() {
        const DATA_1: &'static str = "DATA_1";
        const DATA_2: &'static str = "DATA_2";
        let _ = env_logger::try_init();
        let server_addr = String::from("127.0.0.1:6701");
        let server_group = String::from("indexed_scan_all_test");
        let server = NebServer::new_from_opts(
            &ServerOptions {
                chunk_count: 8,
                memory_size: 512 * 1024 * 1024,
                backup_storage: None,
                wal_storage: None,
                index_enabled: true,
                services: vec![Service::Cell, Service::Query],
            },
            &server_addr,
            &server_group,
        )
        .await;
        // Require schema to be scannable to insert special scan key to the range indexer
        let fields = Field::new(
            "*",
            Type::Map,
            false,
            false,
            Some(vec![
                Field::new(
                    DATA_1,
                    Type::U64,
                    false,
                    false,
                    None,
                    vec![IndexType::Ranged],
                ),
                Field::new(DATA_2, Type::U32, false, false, None, vec![]),
            ]),
            vec![],
        );
        let schema_id_1 = 123;
        let schema_id_2 = 234;
        let schema_1 = Schema::new_with_id(
            schema_id_1,
            &String::from("schema_1"),
            None,
            fields.clone(),
            false,
            true, // Scannable
        );
        let schema_2 = Schema::new_with_id(
            schema_id_2,
            &String::from("schema_2"),
            None,
            fields,
            false,
            true, // Scannable
        );
        let client = server.data_client(&vec![server_addr]).await.unwrap();
        client.new_schema_with_id(schema_1).await.unwrap().unwrap();
        client.new_schema_with_id(schema_2).await.unwrap().unwrap();
        let num = 1024;
        for i in 0..num {
            let id = Id::new(1, i);
            let mut value = OwnedValue::Map(OwnedMap::new());
            value[DATA_1] = OwnedValue::U64(i);
            value[DATA_2] = OwnedValue::U32((i * 2) as u32);
            let cell = OwnedCell::new_with_id(schema_id_1, &id, value);
            client.write_cell(cell).await.unwrap().unwrap();
        }
        let idx_data_client = server.indexed_data_client();
        let mut cursor = idx_data_client
            .scan_all(
                schema_id_1,
                vec![],
                Expr::nothing(),
                Expr::nothing(),
                Ordering::Forward,
            )
            .await
            .unwrap();
        for i in 0..num {
            let id = Id::new(1, i);
            let cell_res = match cursor.next().await {
                Ok(r) => r,
                Err(e) => {
                    panic!("Error next for {}, {:?}", i, e);
                }
            };
            let cell = match cell_res {
                Some(c) => c,
                None => {
                    panic!("Have none for {}", i);
                }
            };
            assert_eq!(id, cell.id());
            assert_eq!(*cell[DATA_1].u64().unwrap(), i);
            assert_eq!(*cell[DATA_2].u32().unwrap(), (i * 2) as u32);
            debug!("Checked cell id {:?} from index", id);
        }
        let out_of_range_item = cursor.next().await.unwrap();
        if let Some(cell) = out_of_range_item {
            panic!("Should not have any more cell. Got id {:?}", cell.id());
        }
        for i in 0..num {
            let id = Id::new(2, i);
            let mut value = OwnedValue::Map(OwnedMap::new());
            value[DATA_1] = OwnedValue::U64(i);
            value[DATA_2] = OwnedValue::U32((i * 3) as u32);
            let cell = OwnedCell::new_with_id(schema_id_2, &id, value);
            client.write_cell(cell).await.unwrap().unwrap();
        }
        let mut cursor = idx_data_client
            .scan_all(
                schema_id_2,
                vec![],
                Expr::nothing(),
                Expr::nothing(),
                Ordering::Forward,
            )
            .await
            .unwrap();
        for i in 0..num {
            let id = Id::new(2, i);
            let cell_res = match cursor.next().await {
                Ok(r) => r,
                Err(e) => {
                    panic!("Error next for {}, {:?}", i, e);
                }
            };
            let cell = match cell_res {
                Some(c) => c,
                None => {
                    panic!("Have none for {}", i);
                }
            };
            assert_eq!(id, cell.id());
            assert_eq!(*cell[DATA_1].u64().unwrap(), i);
            assert_eq!(*cell[DATA_2].u32().unwrap(), (i * 3) as u32);
            debug!("Checked cell id {:?} from index", id);
        }
        let out_of_range_item = cursor.next().await.unwrap();
        if let Some(cell) = out_of_range_item {
            panic!("Should not have any more cell. Got id {:?}", cell.id());
        }
        let mut cursor = idx_data_client
            .scan_all(
                schema_id_1,
                vec![],
                Expr::nothing(),
                Expr::nothing(),
                Ordering::Forward,
            )
            .await
            .unwrap();
        for i in 0..num {
            let id = Id::new(1, i);
            let cell_res = match cursor.next().await {
                Ok(r) => r,
                Err(e) => {
                    panic!("Error next for {}, {:?}", i, e);
                }
            };
            let cell = match cell_res {
                Some(c) => c,
                None => {
                    panic!("Have none for {}", i);
                }
            };
            assert_eq!(id, cell.id());
        }
        // Testing selection
        let select_expr = parse_to_serde_expr("(and (>= DATA_1 10u64) (< DATA_1 100u64))").unwrap()[0].clone();
        let mut cursor = idx_data_client
        .scan_all(
            schema_id_1,
            vec![],
            select_expr,
            Expr::nothing(),
            Ordering::Forward,
        )
        .await
        .unwrap();
        // Start from 10 to 100 due to the selection expression
        for i in 10..100 {
            let id = Id::new(1, i);
            let cell_res = match cursor.next().await {
                Ok(r) => r,
                Err(e) => {
                    panic!("Error next for {}, {:?}", i, e);
                }
            };
            let cell = match cell_res {
                Some(c) => c,
                None => {
                    panic!("Have none for {}", i);
                }
            };
            assert_eq!(id, cell.id());
            assert_eq!(*cell[DATA_1].u64().unwrap(), i);
            assert_eq!(*cell[DATA_2].u32().unwrap(), (i * 2) as u32);
            debug!("Checked cell id {:?} from index", id);
        }
        let out_of_range_item = cursor.next().await.unwrap();
        if let Some(cell) = out_of_range_item {
            panic!("Should not have any more cell. Got id {:?}", cell.id());
        }
    }
}
<commit_msg>consise test case<commit_after>use std::{mem, sync::Arc};

use bifrost::{conshash::ConsistentHashing, raft::client::RaftClient, rpc::RPCError};
use dovahkiin::{expr::serde::Expr, types::OwnedValue};
use futures::stream::{FuturesUnordered, StreamExt};
use itertools::Itertools;

use crate::{
    client::{client_by_server_id, client_by_server_name},
    index::{
        ranged::{client::cursor::ClientCursor, lsm::btree::Ordering},
        EntryKey, IndexerClients, SCHEMA_SCAN_PATT_SIZE,
    },
    ram::cell::{OwnedCell, ReadError},
};

const SCAN_BUFFER_SIZE: u16 = 64;

pub struct IndexedDataClient {
    conshash: Arc<ConsistentHashing>,
    index_clients: Arc<IndexerClients>,
}

pub struct DataCursor<'a> {
    index_cursor: Option<ClientCursor>,
    buffer: Vec<OwnedCell>,
    projection: Vec<u64>,
    selection: Expr,
    proc: Expr,
    client: &'a IndexedDataClient,
    pos: usize,
}

impl IndexedDataClient {
    pub fn new(conshash: &Arc<ConsistentHashing>, raft_client: &Arc<RaftClient>) -> Self {
        Self {
            conshash: conshash.clone(),
            index_clients: Arc::new(IndexerClients::new(conshash, raft_client)),
        }
    }
    pub async fn range_index_scan<'a>(
        &self,
        schema: u32,
        field: u64,
        key: u64,
        selection: OwnedValue,
        projection: OwnedValue,
    ) -> DataCursor<'a> {
        unimplemented!()
    }
    pub async fn scan_all<'a>(
        &'a self,
        schema: u32,
        projection: Vec<u64>, // Column array
        selection: Expr,      // Checker expression
        proc: Expr,
        ordering: Ordering,
    ) -> Result<DataCursor<'a>, RPCError> {
        let key = EntryKey::for_schema(schema);
        let index_cursor = self
            .index_clients
            .range_seek(
                &key,
                ordering,
                SCAN_BUFFER_SIZE,
                Some(SCHEMA_SCAN_PATT_SIZE),
            )
            .await?;
        let mut cursor = DataCursor {
            index_cursor,
            projection,
            selection,
            proc,
            client: self,
            buffer: vec![],
            pos: 0,
        };
        cursor.refresh_batch().await;
        Ok(cursor)
    }
}

impl<'a> DataCursor<'a> {
    pub async fn next(&mut self) -> Result<Option<OwnedCell>, RPCError> {
        if self.buffer.len() <= self.pos {
            if self.next_block().await? {
                if !self.refresh_batch().await {
                    return Ok(None);
                }
            } else {
                return Ok(None);
            }
        }
        if self.buffer.is_empty() {
            return Ok(None);
        }
        let cell = mem::take(&mut self.buffer[self.pos]);
        self.pos += 1;
        return Ok(Some(cell));
    }

    pub async fn next_block(&mut self) -> Result<bool, RPCError> {
        if let Some(cursor) = &mut self.index_cursor {
            if cursor.next_block().await? {
                return Ok(true);
            }
        }
        // If cannot get next block, set the index cursor to none
        // We are done with this cursor
        self.index_cursor = None;
        self.buffer = vec![];
        self.pos = 0;
        return Ok(false);
    }

    pub async fn refresh_batch(&mut self) -> bool {
        if let Some(cursor) = &self.index_cursor {
            let all_ids = cursor.current_block();
            let mut tasks = all_ids
                .iter()
                .enumerate()
                .filter_map(|(i, id)| {
                    self.client
                        .conshash
                        .get_server_id_by(id)
                        .map(|sid| (i, sid, id))
                })
                .group_by(|(_i, sid, _id)| *sid)
                .into_iter()
                .map(|(sid, pairs)| {
                    let mut ids = vec![];
                    let mut idx = vec![];
                    for (i, _, id) in pairs {
                        idx.push(i);
                        ids.push(*id);
                    }
                    let projection = self.projection.clone();
                    let selection = self.selection.clone();
                    let proc = self.proc.clone();
                    let server_name = self.client.conshash.to_server_name(sid);
                    async move {
                        match client_by_server_name(sid, server_name).await {
                            Ok(client) => {
                                let read_res = client
                                    .read_all_cells_proced(ids, projection, selection, proc)
                                    .await
                                    .map(|v| v.into_iter().zip(idx).collect_vec());
                                match read_res {
                                    Ok(cells) => Ok(cells
                                        .into_iter()
                                        .filter_map(|(c, i)| c.ok().map(|c| (c, i)))
                                        .collect_vec()),
                                    Err(e) => return Err(e),
                                }
                            }
                            Err(e) => return Err(e),
                        }
                    }
                })
                .collect::<FuturesUnordered<_>>();
            let mut all_cells = vec![];
            while let Some(task_res) = tasks.next().await {
                if let Ok(mut cells) = task_res {
                    all_cells.append(&mut cells);
                }
            }
            all_cells.sort_by(|(_, i1), (_, i2)| i1.cmp(i2));
            self.buffer = all_cells.into_iter().map(|(c, _)| c).collect_vec();
            self.pos = 0;
            true
        } else {
            self.buffer = vec![];
            self.pos = 0;
            false
        }
    }
}

#[cfg(test)]
mod test {
    use crate::{
        index::ranged::lsm::btree::Ordering,
        ram::{
            cell::OwnedCell,
            schema::{Field, IndexType, Schema},
        },
        server::*,
    };
    use bifrost_hasher::hash_str;
    use dovahkiin::{expr::serde::Expr, types::*, integrated::lisp::*};

    #[tokio::test(flavor = "multi_thread")]
    async fn scan_all() {
        const DATA_1: &'static str = "DATA_1";
        const DATA_2: &'static str = "DATA_2";
        let _ = env_logger::try_init();
        let server_addr = String::from("127.0.0.1:6701");
        let server_group = String::from("indexed_scan_all_test");
        let server = NebServer::new_from_opts(
            &ServerOptions {
                chunk_count: 8,
                memory_size: 512 * 1024 * 1024,
                backup_storage: None,
                wal_storage: None,
                index_enabled: true,
                services: vec![Service::Cell, Service::Query],
            },
            &server_addr,
            &server_group,
        )
        .await;
        // Require schema to be scannable to insert special scan key to the range indexer
        let fields = Field::new(
            "*",
            Type::Map,
            false,
            false,
            Some(vec![
                Field::new(
                    DATA_1,
                    Type::U64,
                    false,
                    false,
                    None,
                    vec![IndexType::Ranged],
                ),
                Field::new(DATA_2, Type::U32, false, false, None, vec![]),
            ]),
            vec![],
        );
        let schema_id_1 = 123;
        let schema_id_2 = 234;
        let schema_1 = Schema::new_with_id(
            schema_id_1,
            &String::from("schema_1"),
            None,
            fields.clone(),
            false,
            true, // Scannable
        );
        let schema_2 = Schema::new_with_id(
            schema_id_2,
            &String::from("schema_2"),
            None,
            fields,
            false,
            true, // Scannable
        );
        let client = server.data_client(&vec![server_addr]).await.unwrap();
        client.new_schema_with_id(schema_1).await.unwrap().unwrap();
        client.new_schema_with_id(schema_2).await.unwrap().unwrap();
        let num = 1024;
        for i in 0..num {
            let id = Id::new(1, i);
            let mut value = OwnedValue::Map(OwnedMap::new());
            value[DATA_1] = OwnedValue::U64(i);
            value[DATA_2] = OwnedValue::U32((i * 2) as u32);
            let cell = OwnedCell::new_with_id(schema_id_1, &id, value);
            client.write_cell(cell).await.unwrap().unwrap();
        }
        let idx_data_client = server.indexed_data_client();
        let mut cursor = idx_data_client
            .scan_all(
                schema_id_1,
                vec![],
                Expr::nothing(),
                Expr::nothing(),
                Ordering::Forward,
            )
            .await
            .unwrap();
        for i in 0..num {
            let id = Id::new(1, i);
            let cell = cursor.next().await.unwrap().unwrap();
            assert_eq!(id, cell.id());
            assert_eq!(*cell[DATA_1].u64().unwrap(), i);
            assert_eq!(*cell[DATA_2].u32().unwrap(), (i * 2) as u32);
            debug!("Checked cell id {:?} from index", id);
        }
        let out_of_range_item = cursor.next().await.unwrap();
        if let Some(cell) = out_of_range_item {
            panic!("Should not have any more cell. Got id {:?}", cell.id());
        }
        for i in 0..num {
            let id = Id::new(2, i);
            let mut value = OwnedValue::Map(OwnedMap::new());
            value[DATA_1] = OwnedValue::U64(i);
            value[DATA_2] = OwnedValue::U32((i * 3) as u32);
            let cell = OwnedCell::new_with_id(schema_id_2, &id, value);
            client.write_cell(cell).await.unwrap().unwrap();
        }
        let mut cursor = idx_data_client
            .scan_all(
                schema_id_2,
                vec![],
                Expr::nothing(),
                Expr::nothing(),
                Ordering::Forward,
            )
            .await
            .unwrap();
        for i in 0..num {
            let id = Id::new(2, i);
            let cell = cursor.next().await.unwrap().unwrap();
            assert_eq!(id, cell.id());
            assert_eq!(*cell[DATA_1].u64().unwrap(), i);
            assert_eq!(*cell[DATA_2].u32().unwrap(), (i * 3) as u32);
            debug!("Checked cell id {:?} from index", id);
        }
        let out_of_range_item = cursor.next().await.unwrap();
        if let Some(cell) = out_of_range_item {
            panic!("Should not have any more cell. Got id {:?}", cell.id());
        }
        let mut cursor = idx_data_client
            .scan_all(
                schema_id_1,
                vec![],
                Expr::nothing(),
                Expr::nothing(),
                Ordering::Forward,
            )
            .await
            .unwrap();
        for i in 0..num {
            let id = Id::new(1, i);
            let cell = cursor.next().await.unwrap().unwrap();
            assert_eq!(id, cell.id());
        }
        // Testing selection
        let select_expr = parse_to_serde_expr("(and (>= DATA_1 10u64) (< DATA_1 100u64))").unwrap()[0].clone();
        let mut cursor = idx_data_client
        .scan_all(
            schema_id_1,
            vec![],
            select_expr,
            Expr::nothing(),
            Ordering::Forward,
        )
        .await
        .unwrap();
        // Start from 10 to 100 due to the selection expression
        for i in 10..100 {
            let id = Id::new(1, i);
            let cell = cursor.next().await.unwrap().unwrap();
            assert_eq!(id, cell.id());
            assert_eq!(*cell[DATA_1].u64().unwrap(), i);
            assert_eq!(*cell[DATA_2].u32().unwrap(), (i * 2) as u32);
            debug!("Checked cell id {:?} from index", id);
        }
        let out_of_range_item = cursor.next().await.unwrap();
        if let Some(cell) = out_of_range_item {
            panic!("Should not have any more cell. Got id {:?}", cell.id());
        }
    }
}
<|endoftext|>


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

///
/// Implementation of the callbacks that the CSS selector engine uses to query the DOM.
///

use core::str::eq_slice;
use newcss::select::SelectHandler;
use script::dom::node::{AbstractNode, LayoutView};

pub struct NodeSelectHandler {
    node: AbstractNode<LayoutView>,
}

fn with_node_name<R>(node: AbstractNode<LayoutView>, f: &fn(&str) -> R) -> R {
    if !node.is_element() {
        fail!(~"attempting to style non-element node");
    }
    do node.with_imm_element |element_n| {
        f(element_n.tag_name)
    }
}

impl SelectHandler<AbstractNode<LayoutView>> for NodeSelectHandler {
    fn with_node_name<R>(&self, node: &AbstractNode<LayoutView>, f: &fn(&str) -> R) -> R {
        with_node_name(*node, f)
    }

    fn named_parent_node(&self, node: &AbstractNode<LayoutView>, name: &str)
                         -> Option<AbstractNode<LayoutView>> {
        match node.parent_node() {
            Some(parent) => {
                do with_node_name(parent) |node_name| {
                    if eq_slice(name, node_name) {
                        Some(parent)
                    } else {
                        None
                    }
                }
            }
            None => None
        }
    }

    fn parent_node(&self, node: &AbstractNode<LayoutView>) -> Option<AbstractNode<LayoutView>> {
        node.parent_node()
    }

    // TODO: Use a Bloom filter.
    fn named_ancestor_node(&self, node: &AbstractNode<LayoutView>, name: &str)
                           -> Option<AbstractNode<LayoutView>> {
        let mut node = *node;
        loop {
            let parent = node.parent_node();
            match parent {
                Some(parent) => {
                    let mut found = false;
                    do with_node_name(parent) |node_name| {
                        if eq_slice(name, node_name) {
                            found = true;
                        }
                    }
                    if found {
                        return Some(parent);
                    }
                    node = parent;
                }
                None => return None
            }
        }
    }

    fn node_is_root(&self, node: &AbstractNode<LayoutView>) -> bool {
        self.parent_node(node).is_none()
    }

    fn node_is_link(&self, node: &AbstractNode<LayoutView>) -> bool {
        if node.is_element() {
            do node.with_imm_element |element| {
                "a" == element.tag_name
            }
        } else {
            false
        }
    }

    fn with_node_id<R>(&self, node: &AbstractNode<LayoutView>, f: &fn(Option<&str>) -> R) -> R {
        if !node.is_element() {
            fail!(~"attempting to style non-element node");
        }
        do node.with_imm_element() |element_n| {
            f(element_n.get_attr("id"))
        }
    }

    fn node_has_id(&self, node: &AbstractNode<LayoutView>, id: &str) -> bool {
        if !node.is_element() {
            fail!(~"attempting to style non-element node");
        }
        do node.with_imm_element |element_n| {
            match element_n.get_attr("id") {
                None => false,
                Some(existing_id) => id == existing_id
            }
        }
    }
}
<commit_msg>Supprot css class selection<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

///
/// Implementation of the callbacks that the CSS selector engine uses to query the DOM.
///

use core::str::eq_slice;
use newcss::select::SelectHandler;
use script::dom::node::{AbstractNode, LayoutView};

pub struct NodeSelectHandler {
    node: AbstractNode<LayoutView>,
}

fn with_node_name<R>(node: AbstractNode<LayoutView>, f: &fn(&str) -> R) -> R {
    if !node.is_element() {
        fail!(~"attempting to style non-element node");
    }
    do node.with_imm_element |element_n| {
        f(element_n.tag_name)
    }
}

impl SelectHandler<AbstractNode<LayoutView>> for NodeSelectHandler {
    fn with_node_name<R>(&self, node: &AbstractNode<LayoutView>, f: &fn(&str) -> R) -> R {
        with_node_name(*node, f)
    }

    fn named_parent_node(&self, node: &AbstractNode<LayoutView>, name: &str)
                         -> Option<AbstractNode<LayoutView>> {
        match node.parent_node() {
            Some(parent) => {
                do with_node_name(parent) |node_name| {
                    if eq_slice(name, node_name) {
                        Some(parent)
                    } else {
                        None
                    }
                }
            }
            None => None
        }
    }

    fn parent_node(&self, node: &AbstractNode<LayoutView>) -> Option<AbstractNode<LayoutView>> {
        node.parent_node()
    }

    // TODO: Use a Bloom filter.
    fn named_ancestor_node(&self, node: &AbstractNode<LayoutView>, name: &str)
                           -> Option<AbstractNode<LayoutView>> {
        let mut node = *node;
        loop {
            let parent = node.parent_node();
            match parent {
                Some(parent) => {
                    let mut found = false;
                    do with_node_name(parent) |node_name| {
                        if eq_slice(name, node_name) {
                            found = true;
                        }
                    }
                    if found {
                        return Some(parent);
                    }
                    node = parent;
                }
                None => return None
            }
        }
    }

    fn node_is_root(&self, node: &AbstractNode<LayoutView>) -> bool {
        self.parent_node(node).is_none()
    }

    fn node_is_link(&self, node: &AbstractNode<LayoutView>) -> bool {
        if node.is_element() {
            do node.with_imm_element |element| {
                "a" == element.tag_name
            }
        } else {
            false
        }
    }

    fn with_node_classes<R>(&self, node: &AbstractNode<LayoutView>, f: &fn(Option<&str>) -> R) -> R {
        if !node.is_element() {
            fail!(~"attempting to style non-element node");
        }
        do node.with_imm_element() |element_n| {
            f(element_n.get_attr("class"))
        }
    }

    fn with_node_id<R>(&self, node: &AbstractNode<LayoutView>, f: &fn(Option<&str>) -> R) -> R {
        if !node.is_element() {
            fail!(~"attempting to style non-element node");
        }
        do node.with_imm_element() |element_n| {
            f(element_n.get_attr("id"))
        }
    }

    fn node_has_id(&self, node: &AbstractNode<LayoutView>, id: &str) -> bool {
        if !node.is_element() {
            fail!(~"attempting to style non-element node");
        }
        do node.with_imm_element |element_n| {
            match element_n.get_attr("id") {
                None => false,
                Some(existing_id) => id == existing_id
            }
        }
    }
}
<|endoftext|>


<commit_before>use color::Color;
use part::*;
use powerline::*;
use std::{env, path};

pub struct Cwd {
	special: &'static str,
	max_length: usize,
	wanted_seg_num: usize,
	resolve_symlinks: bool,
}

impl Cwd {
	pub fn new(special: &'static str, max_length: usize, wanted_seg_num: usize, resolve_symlinks: bool) -> Cwd {
		Cwd {
			special,
			max_length,
			wanted_seg_num,
			resolve_symlinks,
		}
	}
}

fn append_cwd_segments<'a, I>(segments: &mut Vec<Segment>, iter: I)
where
	I: Iterator<Item = &'a str>,
{
	for val in iter {
		segments.push(Segment::special(&format!(" {} ", val), Color::PATH_FG, Color::PATH_BG, '\u{E0B1}', Color::SEPARATOR_FG));
	}
}

impl Part for Cwd {
	fn get_segments(self) -> Result<Vec<Segment>, Error> {
		let current_dir = if self.resolve_symlinks {
			env::current_dir()?
		} else {
			path::PathBuf::from(env::var("PWD")?)
		};

		let mut cwd = current_dir.to_str().unwrap();
		let mut segments = Vec::new();

		if let Some(home_path) = env::home_dir() {
			let home_str = home_path.to_str().unwrap();
			if cwd.starts_with(home_str) {
				segments.push(Segment::simple(&format!(" {} ", self.special), Color::HOME_FG, Color::HOME_BG));
				cwd = &cwd[home_str.len()..]
			}
		}

		let depth = cwd.matches("/").count();
		if (cwd.len() > self.max_length as usize) && (depth > self.wanted_seg_num) {
			let left = self.wanted_seg_num / 2;
			let right = self.wanted_seg_num - left;

			let start = cwd.split("/").skip(1).take(left);
			let end = cwd.split("/").skip(depth - right + 2);

			append_cwd_segments(&mut segments, start);
			segments.push(Segment::special(" \u{2026} ", Color::PATH_FG, Color::PATH_BG, '\u{E0B1}', Color::SEPARATOR_FG));
			append_cwd_segments(&mut segments, end);
		} else {
			append_cwd_segments(&mut segments, cwd.split("/").skip(1));
		};

		if let Some(last) = segments.last_mut() {
			if last.val == "  " {
				last.val = " / ".to_string()
			}
			last.fg = Color::CWD_FG;
			last.sep = '\u{E0B0}';
			last.sep_col = last.bg;
		}

		Ok(segments)
	}
}
<commit_msg>adjust cwd shortening<commit_after>use color::Color;
use part::*;
use powerline::*;
use std::{env, path};

pub struct Cwd {
	special: &'static str,
	max_length: usize,
	wanted_seg_num: usize,
	resolve_symlinks: bool,
}

impl Cwd {
	pub fn new(special: &'static str, max_length: usize, wanted_seg_num: usize, resolve_symlinks: bool) -> Cwd {
		Cwd {
			special,
			max_length,
			wanted_seg_num,
			resolve_symlinks,
		}
	}
}

fn append_cwd_segments<'a, I>(segments: &mut Vec<Segment>, iter: I)
where
	I: Iterator<Item = &'a str>,
{
	for val in iter {
		segments.push(Segment::special(&format!(" {} ", val), Color::PATH_FG, Color::PATH_BG, '\u{E0B1}', Color::SEPARATOR_FG));
	}
}

impl Part for Cwd {
	fn get_segments(self) -> Result<Vec<Segment>, Error> {
		let current_dir = if self.resolve_symlinks {
			env::current_dir()?
		} else {
			path::PathBuf::from(env::var("PWD")?)
		};

		let mut cwd = current_dir.to_str().unwrap();
		let mut segments = Vec::new();

		if let Some(home_path) = env::home_dir() {
			let home_str = home_path.to_str().unwrap();
			if cwd.starts_with(home_str) {
				segments.push(Segment::simple(&format!(" {} ", self.special), Color::HOME_FG, Color::HOME_BG));
				cwd = &cwd[home_str.len()..]
			}
		}

		let depth = cwd.matches("/").count();
		if (cwd.len() > self.max_length as usize) && (depth > self.wanted_seg_num) {
			let left = self.wanted_seg_num / 2;
			let right = self.wanted_seg_num - left;

			let start = cwd.split("/").skip(1).take(left);
			let end = cwd.split("/").skip(depth - right + 1);

			append_cwd_segments(&mut segments, start);
			segments.push(Segment::special(" \u{2026} ", Color::PATH_FG, Color::PATH_BG, '\u{E0B1}', Color::SEPARATOR_FG));
			append_cwd_segments(&mut segments, end);
		} else {
			append_cwd_segments(&mut segments, cwd.split("/").skip(1));
		};

		if let Some(last) = segments.last_mut() {
			if last.val == "  " {
				last.val = " / ".to_string()
			}
			last.fg = Color::CWD_FG;
			last.sep = '\u{E0B0}';
			last.sep_col = last.bg;
		}

		Ok(segments)
	}
}
<|endoftext|>


<commit_before>use std::convert::{TryFrom};
use either::Either;

use crate::values::{AsValueRef, BasicValueEnum, InstructionValue, Value};
use crate::values::FunctionValue;
use crate::values::PointerValue;

use llvm_sys::prelude::LLVMValueRef;
use llvm_sys::core::{LLVMGetTypeKind, LLVMGetElementType, LLVMTypeOf, LLVMGetReturnType};
use llvm_sys::LLVMTypeKind;

use crate::builder::Builder;

/// A value that can be called with the [`Builder::build_call`] instruction.
///
/// In practice, the `F : Into<CallableValue<'ctx>>` bound of [`Builder::build_call`] means it is
/// possible to pass a [`FunctionValue`] to `build_call` directly. It will be implicitly converted
/// into a `CallableValue`.
///
/// ```no_run
/// use inkwell::context::Context;
///
/// // A simple function which calls itself:
/// let context = Context::create();
/// let module = context.create_module("ret");
/// let builder = context.create_builder();
/// let i32_type = context.i32_type();
/// let fn_type = i32_type.fn_type(&[i32_type.into()], false);
/// let fn_value = module.add_function("ret", fn_type, None);
/// let entry = context.append_basic_block(fn_value, "entry");
/// let i32_arg = fn_value.get_first_param().unwrap();
///
/// builder.position_at_end(entry);
///
/// let ret_val = builder.build_call(fn_value, &[i32_arg], "call")
///     .try_as_basic_value()
///     .left()
///     .unwrap();
///
/// builder.build_return(Some(&ret_val));
/// ```
///
/// A [`PointerValue`] cannot be implicitly converted to a `CallableValue` because the pointer may
/// point to a non-function value. Instead we can use [`TryFrom`] and [`TryInto`] to handle this
/// failure case explicitly.
///
/// ```no_run
/// use std::convert::TryFrom;
/// use inkwell::context::Context;
/// use inkwell::values::CallableValue;
///
/// // A simple function which calls itself:
/// let context = Context::create();
/// let module = context.create_module("ret");
/// let builder = context.create_builder();
/// let i32_type = context.i32_type();
/// let fn_type = i32_type.fn_type(&[i32_type.into()], false);
/// let fn_value = module.add_function("ret", fn_type, None);
/// let entry = context.append_basic_block(fn_value, "entry");
/// let i32_arg = fn_value.get_first_param().unwrap();
///
/// builder.position_at_end(entry);
///
/// // take a pointer to the function value
/// let fn_pointer_value = fn_value.as_global_value().as_pointer_value();
///
/// // convert that pointer value into a callable value
/// // explicitly handling the failure case (here with `unwrap`)
/// let callable_value = CallableValue::try_from(fn_pointer_value).unwrap();
///
/// let ret_val = builder.build_call(callable_value, &[i32_arg], "call")
///     .try_as_basic_value()
///     .left()
///     .unwrap();
///
/// builder.build_return(Some(&ret_val));
/// ```
#[derive(Debug)]
pub struct CallableValue<'ctx>(Either<FunctionValue<'ctx>, PointerValue<'ctx>>);

impl<'ctx> crate::values::traits::AsValueRef for CallableValue<'ctx> {
    fn as_value_ref(&self) -> LLVMValueRef {
        use either::Either::*;

        match self.0 {
            Left(function) => function.as_value_ref(),
            Right(pointer) => pointer.as_value_ref(),
        }
    }
}

impl<'ctx> crate::values::AnyValue<'ctx> for CallableValue<'ctx> {}

impl<'ctx> CallableValue<'ctx> {
    pub(crate) fn returns_void(&self) -> bool {
        let return_type = unsafe {
            LLVMGetTypeKind(LLVMGetReturnType(LLVMGetElementType(LLVMTypeOf(self.as_value_ref()))))
        };

        matches!(LLVMTypeKind::LLVMVoidTypeKind, return_type)
    }
}

impl<'ctx> From<FunctionValue<'ctx>> for CallableValue<'ctx> {
    fn from(value: FunctionValue<'ctx>) -> Self {
        Self(Either::Left(value))
    }
}

impl<'ctx> TryFrom<PointerValue<'ctx>> for CallableValue<'ctx> {
    type Error = ();

    fn try_from(value: PointerValue<'ctx>) -> Result<Self, Self::Error> {
        // If using a pointer value, we must validate it's a valid function ptr
        let value_ref = value.as_value_ref();
        let ty_kind = unsafe { LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(value_ref))) };
        let is_a_fn_ptr = matches!(ty_kind, LLVMTypeKind::LLVMFunctionTypeKind);

        if is_a_fn_ptr {
            Ok(Self(Either::Right(value)))
        } else {
            Err(())
        }
    }
}
<commit_msg>fix imports<commit_after>use std::convert::{TryFrom};
use either::Either;

use crate::values::{AsValueRef, BasicValueEnum, InstructionValue, Value};
use crate::values::{FunctionValue, PointerValue, AnyValue};

use crate::traits::AsValue

use llvm_sys::prelude::LLVMValueRef;
use llvm_sys::core::{LLVMGetTypeKind, LLVMGetElementType, LLVMTypeOf, LLVMGetReturnType};
use llvm_sys::LLVMTypeKind;

use crate::builder::Builder;

/// A value that can be called with the [`Builder::build_call`] instruction.
///
/// In practice, the `F : Into<CallableValue<'ctx>>` bound of [`Builder::build_call`] means it is
/// possible to pass a [`FunctionValue`] to `build_call` directly. It will be implicitly converted
/// into a `CallableValue`.
///
/// ```no_run
/// use inkwell::context::Context;
///
/// // A simple function which calls itself:
/// let context = Context::create();
/// let module = context.create_module("ret");
/// let builder = context.create_builder();
/// let i32_type = context.i32_type();
/// let fn_type = i32_type.fn_type(&[i32_type.into()], false);
/// let fn_value = module.add_function("ret", fn_type, None);
/// let entry = context.append_basic_block(fn_value, "entry");
/// let i32_arg = fn_value.get_first_param().unwrap();
///
/// builder.position_at_end(entry);
///
/// let ret_val = builder.build_call(fn_value, &[i32_arg], "call")
///     .try_as_basic_value()
///     .left()
///     .unwrap();
///
/// builder.build_return(Some(&ret_val));
/// ```
///
/// A [`PointerValue`] cannot be implicitly converted to a `CallableValue` because the pointer may
/// point to a non-function value. Instead we can use [`TryFrom`] and [`TryInto`] to handle this
/// failure case explicitly.
///
/// ```no_run
/// use std::convert::TryFrom;
/// use inkwell::context::Context;
/// use inkwell::values::CallableValue;
///
/// // A simple function which calls itself:
/// let context = Context::create();
/// let module = context.create_module("ret");
/// let builder = context.create_builder();
/// let i32_type = context.i32_type();
/// let fn_type = i32_type.fn_type(&[i32_type.into()], false);
/// let fn_value = module.add_function("ret", fn_type, None);
/// let entry = context.append_basic_block(fn_value, "entry");
/// let i32_arg = fn_value.get_first_param().unwrap();
///
/// builder.position_at_end(entry);
///
/// // take a pointer to the function value
/// let fn_pointer_value = fn_value.as_global_value().as_pointer_value();
///
/// // convert that pointer value into a callable value
/// // explicitly handling the failure case (here with `unwrap`)
/// let callable_value = CallableValue::try_from(fn_pointer_value).unwrap();
///
/// let ret_val = builder.build_call(callable_value, &[i32_arg], "call")
///     .try_as_basic_value()
///     .left()
///     .unwrap();
///
/// builder.build_return(Some(&ret_val));
/// ```
#[derive(Debug)]
pub struct CallableValue<'ctx>(Either<FunctionValue<'ctx>, PointerValue<'ctx>>);

impl<'ctx> AsValueRef for CallableValue<'ctx> {
    fn as_value_ref(&self) -> LLVMValueRef {
        use either::Either::*;

        match self.0 {
            Left(function) => function.as_value_ref(),
            Right(pointer) => pointer.as_value_ref(),
        }
    }
}

impl<'ctx> AnyValue<'ctx> for CallableValue<'ctx> {}

impl<'ctx> CallableValue<'ctx> {
    pub(crate) fn returns_void(&self) -> bool {
        let return_type = unsafe {
            LLVMGetTypeKind(LLVMGetReturnType(LLVMGetElementType(LLVMTypeOf(self.as_value_ref()))))
        };

        matches!(LLVMTypeKind::LLVMVoidTypeKind, return_type)
    }
}

impl<'ctx> From<FunctionValue<'ctx>> for CallableValue<'ctx> {
    fn from(value: FunctionValue<'ctx>) -> Self {
        Self(Either::Left(value))
    }
}

impl<'ctx> TryFrom<PointerValue<'ctx>> for CallableValue<'ctx> {
    type Error = ();

    fn try_from(value: PointerValue<'ctx>) -> Result<Self, Self::Error> {
        // If using a pointer value, we must validate it's a valid function ptr
        let value_ref = value.as_value_ref();
        let ty_kind = unsafe { LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(value_ref))) };
        let is_a_fn_ptr = matches!(ty_kind, LLVMTypeKind::LLVMFunctionTypeKind);

        if is_a_fn_ptr {
            Ok(Self(Either::Right(value)))
        } else {
            Err(())
        }
    }
}
<|endoftext|>


<commit_before>use super::frontend_prelude::*;

use crate::models::{CrateOwner, CrateOwnerInvitation, OwnerKind};
use crate::schema::{crate_owner_invitations, crate_owners};
use crate::views::{EncodableCrateOwnerInvitation, InvitationResponse};

/// Handles the `GET /me/crate_owner_invitations` route.
pub fn list(req: &mut dyn RequestExt) -> EndpointResult {
    let user_id = { req.authenticate()? }.user_id();
    let conn = &*req.db_conn()?;

    let crate_owner_invitations = crate_owner_invitations::table
        .filter(crate_owner_invitations::invited_user_id.eq(user_id))
        .load::<CrateOwnerInvitation>(&*conn)?
        .into_iter()
        .map(|i| i.encodable(conn))
        .collect();

    #[derive(Serialize)]
    struct R {
        crate_owner_invitations: Vec<EncodableCrateOwnerInvitation>,
    }
    Ok(req.json(&R {
        crate_owner_invitations,
    }))
}

#[derive(Deserialize)]
struct OwnerInvitation {
    crate_owner_invite: InvitationResponse,
}

/// Handles the `PUT /me/crate_owner_invitations/:crate_id` route.
pub fn handle_invite(req: &mut dyn RequestExt) -> EndpointResult {
    let mut body = String::new();
    req.body().read_to_string(&mut body)?;

    let crate_invite: OwnerInvitation =
        serde_json::from_str(&body).map_err(|_| bad_request("invalid json request"))?;

    let crate_invite = crate_invite.crate_owner_invite;
    let user_id = req.authenticate()?.user_id();
    let conn = &*req.db_conn()?;

    if crate_invite.accepted {
        accept_invite(req, conn, crate_invite, user_id)
    } else {
        decline_invite(req, conn, crate_invite, user_id)
    }
}

/// Handles the `PUT /me/crate_owner_invitations/accept/:token` route.
pub fn handle_invite_with_token(req: &mut dyn RequestExt) -> EndpointResult {
    let conn = req.db_conn()?;
    let req_token = &req.params()["token"];

    let crate_owner_invite: CrateOwnerInvitation = crate_owner_invitations::table
        .filter(crate_owner_invitations::token.eq(req_token))
        .first::<CrateOwnerInvitation>(&*conn)?;

    let invite_reponse = InvitationResponse {
        crate_id: crate_owner_invite.crate_id,
        accepted: true,
    };
    accept_invite(
        req,
        &conn,
        invite_reponse,
        crate_owner_invite.invited_user_id,
    )
}

fn accept_invite(
    req: &dyn RequestExt,
    conn: &PgConnection,
    crate_invite: InvitationResponse,
    user_id: i32,
) -> EndpointResult {
    use diesel::{delete, insert_into};

    conn.transaction(|| {
        let pending_crate_owner = crate_owner_invitations::table
            .find((user_id, crate_invite.crate_id))
            .first::<CrateOwnerInvitation>(&*conn)?;

        insert_into(crate_owners::table)
            .values(&CrateOwner {
                crate_id: crate_invite.crate_id,
                owner_id: user_id,
                created_by: pending_crate_owner.invited_by_user_id,
                owner_kind: OwnerKind::User as i32,
                email_notifications: true,
            })
            .on_conflict(crate_owners::table.primary_key())
            .do_update()
            .set(crate_owners::deleted.eq(false))
            .execute(conn)?;
        delete(crate_owner_invitations::table.find((user_id, crate_invite.crate_id)))
            .execute(conn)?;

        #[derive(Serialize)]
        struct R {
            crate_owner_invitation: InvitationResponse,
        }
        Ok(req.json(&R {
            crate_owner_invitation: crate_invite,
        }))
    })
}

fn decline_invite(
    req: &dyn RequestExt,
    conn: &PgConnection,
    crate_invite: InvitationResponse,
    user_id: i32,
) -> EndpointResult {
    use diesel::delete;

    delete(crate_owner_invitations::table.find((user_id, crate_invite.crate_id))).execute(conn)?;

    #[derive(Serialize)]
    struct R {
        crate_owner_invitation: InvitationResponse,
    }

    Ok(req.json(&R {
        crate_owner_invitation: crate_invite,
    }))
}
<commit_msg>Remove unnecessary braces<commit_after>use super::frontend_prelude::*;

use crate::models::{CrateOwner, CrateOwnerInvitation, OwnerKind};
use crate::schema::{crate_owner_invitations, crate_owners};
use crate::views::{EncodableCrateOwnerInvitation, InvitationResponse};

/// Handles the `GET /me/crate_owner_invitations` route.
pub fn list(req: &mut dyn RequestExt) -> EndpointResult {
    let user_id = req.authenticate()?.user_id();
    let conn = &*req.db_conn()?;

    let crate_owner_invitations = crate_owner_invitations::table
        .filter(crate_owner_invitations::invited_user_id.eq(user_id))
        .load::<CrateOwnerInvitation>(&*conn)?
        .into_iter()
        .map(|i| i.encodable(conn))
        .collect();

    #[derive(Serialize)]
    struct R {
        crate_owner_invitations: Vec<EncodableCrateOwnerInvitation>,
    }
    Ok(req.json(&R {
        crate_owner_invitations,
    }))
}

#[derive(Deserialize)]
struct OwnerInvitation {
    crate_owner_invite: InvitationResponse,
}

/// Handles the `PUT /me/crate_owner_invitations/:crate_id` route.
pub fn handle_invite(req: &mut dyn RequestExt) -> EndpointResult {
    let mut body = String::new();
    req.body().read_to_string(&mut body)?;

    let crate_invite: OwnerInvitation =
        serde_json::from_str(&body).map_err(|_| bad_request("invalid json request"))?;

    let crate_invite = crate_invite.crate_owner_invite;
    let user_id = req.authenticate()?.user_id();
    let conn = &*req.db_conn()?;

    if crate_invite.accepted {
        accept_invite(req, conn, crate_invite, user_id)
    } else {
        decline_invite(req, conn, crate_invite, user_id)
    }
}

/// Handles the `PUT /me/crate_owner_invitations/accept/:token` route.
pub fn handle_invite_with_token(req: &mut dyn RequestExt) -> EndpointResult {
    let conn = req.db_conn()?;
    let req_token = &req.params()["token"];

    let crate_owner_invite: CrateOwnerInvitation = crate_owner_invitations::table
        .filter(crate_owner_invitations::token.eq(req_token))
        .first::<CrateOwnerInvitation>(&*conn)?;

    let invite_reponse = InvitationResponse {
        crate_id: crate_owner_invite.crate_id,
        accepted: true,
    };
    accept_invite(
        req,
        &conn,
        invite_reponse,
        crate_owner_invite.invited_user_id,
    )
}

fn accept_invite(
    req: &dyn RequestExt,
    conn: &PgConnection,
    crate_invite: InvitationResponse,
    user_id: i32,
) -> EndpointResult {
    use diesel::{delete, insert_into};

    conn.transaction(|| {
        let pending_crate_owner = crate_owner_invitations::table
            .find((user_id, crate_invite.crate_id))
            .first::<CrateOwnerInvitation>(&*conn)?;

        insert_into(crate_owners::table)
            .values(&CrateOwner {
                crate_id: crate_invite.crate_id,
                owner_id: user_id,
                created_by: pending_crate_owner.invited_by_user_id,
                owner_kind: OwnerKind::User as i32,
                email_notifications: true,
            })
            .on_conflict(crate_owners::table.primary_key())
            .do_update()
            .set(crate_owners::deleted.eq(false))
            .execute(conn)?;
        delete(crate_owner_invitations::table.find((user_id, crate_invite.crate_id)))
            .execute(conn)?;

        #[derive(Serialize)]
        struct R {
            crate_owner_invitation: InvitationResponse,
        }
        Ok(req.json(&R {
            crate_owner_invitation: crate_invite,
        }))
    })
}

fn decline_invite(
    req: &dyn RequestExt,
    conn: &PgConnection,
    crate_invite: InvitationResponse,
    user_id: i32,
) -> EndpointResult {
    use diesel::delete;

    delete(crate_owner_invitations::table.find((user_id, crate_invite.crate_id))).execute(conn)?;

    #[derive(Serialize)]
    struct R {
        crate_owner_invitation: InvitationResponse,
    }

    Ok(req.json(&R {
        crate_owner_invitation: crate_invite,
    }))
}
<|endoftext|>


<commit_before>use std::ptr;

use libc::{c_void, int32_t, uint32_t};

use raw;

#[allow(unused_variables)]
extern fn ping(
    data: *mut c_void,
    wl_shell_surface: *mut raw::wl_shell_surface,
    serial: uint32_t
) {
    println!("wl_shell_surface.ping serial = {}", serial);
}

#[allow(unused_variables)]
extern fn configure(
    data: *mut c_void,
    wl_shell_surface: *mut raw::wl_shell_surface,
    edges: uint32_t,
    width: int32_t,
    height: int32_t
) {
    println!("wl_shell_surface.configure");
}

#[allow(unused_variables)]
extern fn popup_done(
    data: *mut c_void,
    wl_shell_surface: *mut raw::wl_shell_surface,
) {
    println!("wl_shell_surface.popup_done");
}

static LISTENER: raw::wl_shell_surface_listener =
    raw::wl_shell_surface_listener {
        ping: ping,
        configure: configure,
        popup_done: popup_done
    };

pub struct ShellSurface {
    ptr: *mut raw::wl_shell_surface
}

impl ShellSurface {
    pub unsafe fn from_ptr(ptr: *mut raw::wl_shell_surface) -> ShellSurface {
        raw::wl_shell_surface_add_listener(
            ptr,
            &LISTENER,
            ptr::null_mut()
        );
        ShellSurface { ptr: ptr }
    }
    pub fn set_toplevel(&mut self) {
        unsafe {
            raw::wl_shell_surface_set_toplevel(self.ptr);
        }
    }
}

impl Drop for ShellSurface {
    fn drop(&mut self) {
        unsafe {
            raw::wl_shell_surface_destroy(self.ptr)
        }
    }
}
<commit_msg>Added response to pings<commit_after>use std::ptr;

use libc::{c_void, int32_t, uint32_t};

use raw;

#[allow(unused_variables)]
extern fn ping(
    data: *mut c_void,
    wl_shell_surface: *mut raw::wl_shell_surface,
    serial: uint32_t
) {
    println!("wl_shell_surface.ping serial = {}", serial);
    unsafe {
        raw::wl_shell_surface_pong(wl_shell_surface, serial);
    }
}

#[allow(unused_variables)]
extern fn configure(
    data: *mut c_void,
    wl_shell_surface: *mut raw::wl_shell_surface,
    edges: uint32_t,
    width: int32_t,
    height: int32_t
) {
    println!("wl_shell_surface.configure");
}

#[allow(unused_variables)]
extern fn popup_done(
    data: *mut c_void,
    wl_shell_surface: *mut raw::wl_shell_surface,
) {
    println!("wl_shell_surface.popup_done");
}

static LISTENER: raw::wl_shell_surface_listener =
    raw::wl_shell_surface_listener {
        ping: ping,
        configure: configure,
        popup_done: popup_done
    };

pub struct ShellSurface {
    ptr: *mut raw::wl_shell_surface
}

impl ShellSurface {
    pub unsafe fn from_ptr(ptr: *mut raw::wl_shell_surface) -> ShellSurface {
        raw::wl_shell_surface_add_listener(
            ptr,
            &LISTENER,
            ptr::null_mut()
        );
        ShellSurface { ptr: ptr }
    }
    pub fn set_toplevel(&mut self) {
        unsafe {
            raw::wl_shell_surface_set_toplevel(self.ptr);
        }
    }
}

impl Drop for ShellSurface {
    fn drop(&mut self) {
        unsafe {
            raw::wl_shell_surface_destroy(self.ptr)
        }
    }
}
<|endoftext|>


<commit_before>use anyhow::Result;
use bytes::Bytes;
use std::collections::HashMap;
use std::time::Duration;
use tide::Request;

use async_std::sync::{channel, Arc, Receiver, Sender};
use futures::sink::SinkExt;
use futures::stream::StreamExt;
// use futures_util::stream::StreamExt as UtilsStreamExt;
use tungstenite::Message;

use async_std::task;

#[derive(Clone, Copy)]
#[repr(u8)]
enum SystemCommand {
    WakeUp = 1,
    Disconnect = 2,
}

#[derive(Clone, Debug)]
enum ReceiverType {
    System,
    Hypercore,
    Client,
}

#[derive(Clone)]
struct State {
    system_commands: Receiver<Bytes>,
    writers: HashMap<String, Sender<Bytes>>,
    readers: HashMap<String, Receiver<Bytes>>,
}

#[derive(Clone)]
struct WrappedData {
    data: Bytes,
    receiver_type: ReceiverType,
    id: Option<String>,
}

type WrappedBytesClosure = Box<dyn Fn(Bytes) -> WrappedData + Send + Sync>;
// type WrappedWebSocketClosure =
//     Box<dyn Fn(Result<tungstenite::Message, std::io::Error>) -> WrappedData + Send + Sync>;

async fn async_main(initial_state: State) -> Result<()> {
    let mut app = tide::with_state(initial_state);

    app.at("/ws").get(|req: Request<State>| async move {
        tide::websocket::upgrade(req, |_req, handle| async move {
            // https://docs.rs/async-tungstenite/0.10.0/async_tungstenite/struct.WebSocketStream.html
            let (mut ws_writer, mut ws_reader) = handle.into_inner().split();
            // Handshake the inner protocol
            // let init_msg: Arc<String> =
            //     Arc::new(ws_reader.next().await.unwrap().unwrap().to_string());

            let init_msg: String = ws_reader.next().await.unwrap().unwrap().to_string();

            // let system_command_reader =
            //     _req.state()
            //         .system_commands
            //         .clone()
            //         .map(Box::new(|data| WrappedData {
            //             data,
            //             receiver_type: ReceiverType::System,
            //             id: None,
            //         }) as WrappedBytesClosure);
            // let system_command_reader = ;
            dbg!(&init_msg);
            let hypercore_writer = _req.state().writers[&*init_msg].clone();
            // let reader = _req.state().readers[&*init_msg]
            //     .clone()
            //     .map(Box::new(move |data| WrappedData {
            //         data,
            //         receiver_type: ReceiverType::System,
            //         id: Some((&*init_msg).to_string()),
            //     }) as WrappedBytesClosure);
            ws_writer
                .send(Message::Text("reply-to-init".to_string()))
                .await
                .unwrap();

            // use futures::future::Either;
            // let client_reader_writer =
            //     ws.get_ref()
            //         .clone()
            //         .map(
            //             Box::new(move |_msg: Result<tungstenite::Message, _>| WrappedData {
            //                 data: Bytes::from(_msg.ok().unwrap().into_data()),
            //                 receiver_type: ReceiverType::Client,
            //                 id: None,
            //             }) as WrappedWebSocketClosure,
            //         );

            // let streams: Vec<
            //     Either<
            //         futures::stream::Map<
            //             async_std::sync::Receiver<bytes::Bytes>,
            //             std::boxed::Box<
            //                 dyn std::ops::Fn(bytes::Bytes) -> WrappedData
            //                     + std::marker::Send
            //                     + std::marker::Sync,
            //             >,
            //         >,
            //         futures::stream::Map<
            //             async_std::sync::Receiver<bytes::Bytes>,
            //             std::boxed::Box<
            //                 dyn std::ops::Fn(bytes::Bytes) -> WrappedData
            //                     + std::marker::Send
            //                     + std::marker::Sync,
            //             >,
            //         >,
            //     >,
            // > = vec![
            //     Either::Left(system_command_reader),
            //     Either::Left(reader),
            //     Either::Right(client_reader_writer),
            // ];
            //
            //
            let (client_sender, client_receiver): (Sender<Bytes>, Receiver<Bytes>) = channel(1000);
            // let client_reader = client_receiver
            //     .clone()
            //     .map(Box::new(move |data| WrappedData {
            //         data,
            //         receiver_type: ReceiverType::Client,
            //         id: None,
            //     }) as WrappedBytesClosure);

            // Start polling
            //
            // Use https://docs.rs/futures/0.3.7/futures/stream/fn.select_all.html
            // to merge many streams.
            //

            task::Builder::new()
                .name(init_msg.clone())
                .spawn(async move {
                    while let Some(wrapped_value) = futures::stream::select_all(vec![
                        _req.state()
                            .system_commands
                            .clone()
                            .map(Box::new(|data| WrappedData {
                                data,
                                receiver_type: ReceiverType::System,
                                id: None,
                            }) as WrappedBytesClosure),
                        _req.state().readers[&String::from(task::current().name().unwrap())]
                            .clone()
                            .map(Box::new(move |data| WrappedData {
                                data,
                                receiver_type: ReceiverType::Hypercore,
                                id: Some(String::from(task::current().name().unwrap())),
                            }) as WrappedBytesClosure), /*, reader, client_reader*/
                        client_receiver
                            .clone()
                            .map(Box::new(move |data| WrappedData {
                                data,
                                receiver_type: ReceiverType::Client,
                                id: None,
                            }) as WrappedBytesClosure),
                    ])
                    .next()
                    .await
                    {
                        dbg!("got value of type {}", wrapped_value.receiver_type);
                        ws_writer
                            .send(tungstenite::Message::Binary(
                                wrapped_value.data.as_ref().to_vec(),
                            ))
                            .await
                            .unwrap();
                        dbg!("got result");
                    }
                })
                .unwrap();

            // let msg = ws.next().await.unwrap().unwrap();
            // dbg!(&msg);
            // ws.send(msg).await.unwrap();
            loop {
                let incoming_msg = ws_reader.next().await;
                let msg = incoming_msg.unwrap().unwrap();
                client_sender.send(Bytes::from(msg.into_data())).await;
            }
        })
    });

    app.listen("0.0.0.0:8080").await?;
    Ok(())
}

fn main() -> Result<()> {
    fern::Dispatch::new()
        .format(|out, message, record| {
            out.finish(format_args!(
                "{}[{}][{}] {}",
                chrono::Local::now().format("[%Y-%m-%d %H:%M:%S]"),
                record.target(),
                record.level(),
                message
            ))
        })
        .level(log::LevelFilter::Debug)
        .chain(std::io::stdout())
        .apply()?;
    let (ping_sender, system_command_receiver) = channel(1000);
    let (demo_sender, demo_receiver) = channel(1000);
    let initial_state = State {
        system_commands: system_command_receiver,
        writers: [("demo".to_string(), demo_sender)]
            .iter()
            .cloned()
            .collect(),
        readers: [("demo".to_string(), demo_receiver)]
            .iter()
            .cloned()
            .collect(),
    };

    // TODO: This should be used on SIGINT/SIGTERM
    let disconnect_sender = ping_sender.clone();

    // Need to start a system executor to send the WakeUp command, we send it once per 5 seconds so
    // that the listener will send a WS Ping every 30 to 35 seconds.
    task::spawn(async move {
        loop {
            task::sleep(Duration::from_millis(5000)).await;
            dbg!("Sending WakeUp");
            ping_sender
                .send(Bytes::from_static(&[SystemCommand::WakeUp as u8]))
                .await;
        }
    });

    futures::executor::block_on(async_main(initial_state))?;

    Ok(())
}
<commit_msg>Much simpler way of passing in a varible<commit_after>use anyhow::Result;
use bytes::Bytes;
use std::collections::HashMap;
use std::time::Duration;
use tide::Request;

use async_std::sync::{channel, Arc, Receiver, Sender};
use futures::sink::SinkExt;
use futures::stream::StreamExt;
use tungstenite::Message;

use async_std::task;

#[derive(Clone, Copy)]
#[repr(u8)]
enum SystemCommand {
    WakeUp = 1,
    Disconnect = 2,
}

#[derive(Clone, Debug)]
enum ReceiverType {
    System,
    Hypercore,
    Client,
}

#[derive(Clone)]
struct State {
    system_commands: Receiver<Bytes>,
    writers: HashMap<Bytes, Sender<Bytes>>,
    readers: HashMap<Bytes, Receiver<Bytes>>,
}

#[derive(Clone)]
struct WrappedData {
    data: Bytes,
    receiver_type: ReceiverType,
    id: Option<Bytes>,
}

type WrappedBytesClosure = Box<dyn Fn(Bytes) -> WrappedData + Send + Sync>;
// type WrappedWebSocketClosure =
//     Box<dyn Fn(Result<tungstenite::Message, std::io::Error>) -> WrappedData + Send + Sync>;

async fn async_main(initial_state: State) -> Result<()> {
    let mut app = tide::with_state(initial_state);

    app.at("/ws").get(|req: Request<State>| async move {
        tide::websocket::upgrade(req, |_req, handle| async move {
            // https://docs.rs/async-tungstenite/0.10.0/async_tungstenite/struct.WebSocketStream.html
            let (mut ws_writer, mut ws_reader) = handle.into_inner().split();
            let init_msg: Bytes = Bytes::from(ws_reader.next().await.unwrap().unwrap().into_data());
            dbg!(&init_msg);
            let hypercore_writer = _req.state().writers[&*init_msg].clone();
            ws_writer
                .send(Message::Text("reply-to-init".to_string()))
                .await
                .unwrap();
            let (client_sender, client_receiver): (Sender<Bytes>, Receiver<Bytes>) = channel(1000);
            let init_msg: Arc<Bytes> = Arc::new(init_msg.clone());
            task::spawn(async move {
                let receivers = collect_receivers(_req.state(), client_receiver.clone(), init_msg);
                let mut merged = futures::stream::select_all(receivers);
                while let Some(wrapped_value) = merged.next().await {
                    dbg!("got value of type {}", wrapped_value.receiver_type);
                    ws_writer
                        .send(tungstenite::Message::Binary(
                            wrapped_value.data.as_ref().to_vec(),
                        ))
                        .await
                        .unwrap();
                    dbg!("got result");
                }
            });
            loop {
                let incoming_msg = ws_reader.next().await;
                let msg = incoming_msg.unwrap().unwrap();
                client_sender.send(Bytes::from(msg.into_data())).await;
            }
        })
    });

    app.listen("0.0.0.0:8080").await?;
    Ok(())
}

fn collect_receivers(
    state: &State,
    client_receiver: Receiver<Bytes>,
    init_msg: Arc<Bytes>,
) -> Vec<futures::stream::Map<async_std::sync::Receiver<bytes::Bytes>, WrappedBytesClosure>> {
    let reader = state.readers[init_msg.as_ref()].clone();
    vec![
        state
            .system_commands
            .clone()
            .map(Box::new(|data| WrappedData {
                data,
                receiver_type: ReceiverType::System,
                id: None,
            }) as WrappedBytesClosure),
        reader.map(Box::new(move |data| WrappedData {
            data,
            receiver_type: ReceiverType::Hypercore,
            id: Some((*init_msg).clone()),
        }) as WrappedBytesClosure),
        client_receiver.map(Box::new(move |data| WrappedData {
            data,
            receiver_type: ReceiverType::Client,
            id: None,
        }) as WrappedBytesClosure),
    ]
}

fn main() -> Result<()> {
    fern::Dispatch::new()
        .format(|out, message, record| {
            out.finish(format_args!(
                "{}[{}][{}] {}",
                chrono::Local::now().format("[%Y-%m-%d %H:%M:%S]"),
                record.target(),
                record.level(),
                message
            ))
        })
        .level(log::LevelFilter::Debug)
        .chain(std::io::stdout())
        .apply()?;
    let (ping_sender, system_command_receiver) = channel(1000);
    let (demo_sender, demo_receiver) = channel(1000);
    let initial_state = State {
        system_commands: system_command_receiver,
        writers: [(Bytes::from_static("demo".as_bytes()), demo_sender)]
            .iter()
            .cloned()
            .collect(),
        readers: [(Bytes::from_static("demo".as_bytes()), demo_receiver)]
            .iter()
            .cloned()
            .collect(),
    };

    // TODO: This should be used on SIGINT/SIGTERM
    let disconnect_sender = ping_sender.clone();

    // Need to start a system executor to send the WakeUp command, we send it once per 5 seconds so
    // that the listener will send a WS Ping every 30 to 35 seconds.
    task::spawn(async move {
        loop {
            task::sleep(Duration::from_millis(5000)).await;
            dbg!("Sending WakeUp");
            ping_sender
                .send(Bytes::from_static(&[SystemCommand::WakeUp as u8]))
                .await;
        }
    });

    futures::executor::block_on(async_main(initial_state))?;

    Ok(())
}
<|endoftext|>