<commit_before>use csv;
use regex::Regex;
use std::result::Result;
use std::str;
use std::process;
use curl::http;
use rustc_serialize::json;

fn get_page(url: String, token: &str) -> http::Response {
    println!("Fetching {:?}", url);
    let auth_header = format!("token {}", token);
    let res = http::handle()
                   .get(url)
                   .header("Authorization", &auth_header)
                   .header("User-Agent", "Github-Issues-CLI")
                   .header("Accept", "application/vnd.github.v3+json")
                   .exec()
                   .unwrap_or_else(|e| process::exit(1));

    if res.get_code() != 200 {
        match str::from_utf8(res.get_body()) {
            Ok(b) => {
                println!("\n*******************************************************************************");
                println!("{:?}", json::decode::<GithubError>(b).ok());
                println!("*******************************************************************************\n");
                process::exit(1)
            }
            Err(..) => {
                println!("Unable to parse the response from Github");
                process::exit(1)
            }
        }
    }

    res
}

fn next_url(link: String) -> Option<String> {
    let re = Regex::new(r"<([^;]+)>;\s*rel=.next.").unwrap();
    match re.captures(&link) {
        None => None,
        Some(cs) => cs.at(1).as_ref().map(|x| x.to_string())
    }
}

fn to_issues(raw: &[u8]) -> Result<Issues, json::DecoderError> {
    match str::from_utf8(raw) {
        Ok(b) => json::decode(b),
        Err(..) => {
            println!("Unable to parse the response from Github");
            process::exit(1)
        }
    }
}

pub fn run(owner: &str,
           repo: &str,
           oauth_token: String,
           labels: Vec<String>,
           output_file: String) {

    let page = 1;
    let labels_pair = if labels.is_empty() { "".to_string() }
                      else { format!("&labels={}", labels.join(",")) };
    let url = format!("https://api.github.com/repos/{}/{}/issues?state=all&page={}{}",
                      owner, repo, page, labels_pair);

    let res = get_page(url, &oauth_token);
    let mut issues = to_issues(res.get_body()).unwrap();

    // A Link header is not present if the requested collection has less than
    // _pagesize_.
    match res.get_headers().get("link") {
        Some(links) => {
            let mut nurl = next_url(links.first().unwrap().clone());

            while let Some(nu) = nurl {
                let r = get_page(nu.to_string(), &oauth_token);
                issues.extend(to_issues(r.get_body()).unwrap());

                let link = r.get_headers().get("link").unwrap()
                                          .first().unwrap()
                                          .clone();
                nurl = next_url(link);
            }
        }
        _ => {}
    }

    // let mut wtr = csv::Writer::from_memory();
    let mut wtr = csv::Writer::from_file(output_file).unwrap();
    let headers = ("number",
                   "title",
                   "state",
                   "created_at",
                   "closed_at",
                   "assignee",
                   "user",
                   "labels",
                   "body");
    wtr.encode(headers);

    println!("Total issues collected: {:?}", issues.len());

    for issue in issues {
        let labels = issue.labels.iter()
                                 .map(|x| x.name.clone())
                                 .collect::<Vec<String>>()
                                 .join(",");
        let user = issue.user;
        let assignee = issue.assignee;

        let row = (issue.number,
                   issue.title,
                   issue.state,
                   issue.created_at,
                   issue.closed_at,
                   assignee,
                   user,
                   labels,
                   issue.body);

        // println!("{:?}", row);
        // let result = wtr.encode(row);
        // println!("{:?}", result.is_ok());
        wtr.encode(row);
    }

    // println!("{:?}", wtr.as_string());
}

#[derive(Debug, RustcDecodable, RustcEncodable)]
struct Issue {
    assignee: Option<User>,
    body: Option<String>,
    created_at: Option<String>,
    closed_at: Option<String>,
    labels: Labels,
    number: u32,
    state: Option<String>,
    title: Option<String>,
    user: Option<User>,
}

type Issues = Vec<Issue>;

type Labels = Vec<Label>;

#[derive(Debug, RustcDecodable, RustcEncodable)]
struct Label {
    color: String,
    name: String,
}

#[derive(Debug, RustcDecodable, RustcEncodable)]
struct User {
    login: String,
}

#[derive(Debug, RustcDecodable, RustcEncodable)]
struct GithubError {
    message: String,
    documentation_url: String,
}
<commit_msg>Add explicit filter=all to not rely on implicit token behaviour<commit_after>use csv;
use regex::Regex;
use std::result::Result;
use std::str;
use std::process;
use curl::http;
use rustc_serialize::json;

fn get_page(url: String, token: &str) -> http::Response {
    println!("Fetching {:?}", url);
    let auth_header = format!("token {}", token);
    let res = http::handle()
                   .get(url)
                   .header("Authorization", &auth_header)
                   .header("User-Agent", "Github-Issues-CLI")
                   .header("Accept", "application/vnd.github.v3+json")
                   .exec()
                   .unwrap_or_else(|e| process::exit(1));

    if res.get_code() != 200 {
        match str::from_utf8(res.get_body()) {
            Ok(b) => {
                println!("\n*******************************************************************************");
                println!("{:?}", json::decode::<GithubError>(b).ok());
                println!("*******************************************************************************\n");
                process::exit(1)
            }
            Err(..) => {
                println!("Unable to parse the response from Github");
                process::exit(1)
            }
        }
    }

    res
}

fn next_url(link: String) -> Option<String> {
    let re = Regex::new(r"<([^;]+)>;\s*rel=.next.").unwrap();
    match re.captures(&link) {
        None => None,
        Some(cs) => cs.at(1).as_ref().map(|x| x.to_string())
    }
}

fn to_issues(raw: &[u8]) -> Result<Issues, json::DecoderError> {
    match str::from_utf8(raw) {
        Ok(b) => json::decode(b),
        Err(..) => {
            println!("Unable to parse the response from Github");
            process::exit(1)
        }
    }
}

pub fn run(owner: &str,
           repo: &str,
           oauth_token: String,
           labels: Vec<String>,
           output_file: String) {

    let page = 1;
    let labels_pair = if labels.is_empty() { "".to_string() }
                      else { format!("&labels={}", labels.join(",")) };
    let url = format!("https://api.github.com/repos/{}/{}/issues?filter=all&state=all&page={}{}",
                      owner, repo, page, labels_pair);

    let res = get_page(url, &oauth_token);
    let mut issues = to_issues(res.get_body()).unwrap();

    // A Link header is not present if the requested collection has less than
    // _pagesize_.
    match res.get_headers().get("link") {
        Some(links) => {
            let mut nurl = next_url(links.first().unwrap().clone());

            while let Some(nu) = nurl {
                let r = get_page(nu.to_string(), &oauth_token);
                issues.extend(to_issues(r.get_body()).unwrap());

                let link = r.get_headers().get("link").unwrap()
                                          .first().unwrap()
                                          .clone();
                nurl = next_url(link);
            }
        }
        _ => {}
    }

    // let mut wtr = csv::Writer::from_memory();
    let mut wtr = csv::Writer::from_file(output_file).unwrap();
    let headers = ("number",
                   "title",
                   "state",
                   "created_at",
                   "closed_at",
                   "assignee",
                   "user",
                   "labels",
                   "body");
    wtr.encode(headers);

    println!("Total issues collected: {:?}", issues.len());

    for issue in issues {
        let labels = issue.labels.iter()
                                 .map(|x| x.name.clone())
                                 .collect::<Vec<String>>()
                                 .join(",");
        let user = issue.user;
        let assignee = issue.assignee;

        let row = (issue.number,
                   issue.title,
                   issue.state,
                   issue.created_at,
                   issue.closed_at,
                   assignee,
                   user,
                   labels,
                   issue.body);

        // println!("{:?}", row);
        // let result = wtr.encode(row);
        // println!("{:?}", result.is_ok());
        wtr.encode(row);
    }

    // println!("{:?}", wtr.as_string());
}

#[derive(Debug, RustcDecodable, RustcEncodable)]
struct Issue {
    assignee: Option<User>,
    body: Option<String>,
    created_at: Option<String>,
    closed_at: Option<String>,
    labels: Labels,
    number: u32,
    state: Option<String>,
    title: Option<String>,
    user: Option<User>,
}

type Issues = Vec<Issue>;

type Labels = Vec<Label>;

#[derive(Debug, RustcDecodable, RustcEncodable)]
struct Label {
    color: String,
    name: String,
}

#[derive(Debug, RustcDecodable, RustcEncodable)]
struct User {
    login: String,
}

#[derive(Debug, RustcDecodable, RustcEncodable)]
struct GithubError {
    message: String,
    documentation_url: String,
}
<|endoftext|>


<commit_before>// vim: tw=80

use mockall;
use mockall_derive::mock;
use std::default::Default;

/// Mocking a trait with associated types currently requires manual mocking.
/// TODO: add derive support for this, perhaps by providing the "type T=u32" as
/// an attr argument to mock.
#[test]
fn associated_types() {
    trait A {
        type T;
        fn foo(&self, x: Self::T) -> Self::T;
    }

    #[derive(Default)]
    struct MockA {
        e: ::mockall::Expectations,
    }
    impl A for MockA {
        type T=u32;

        fn foo(&self, x: Self::T) -> Self::T {
            self.e.called::<Self::T, Self::T>("foo", x)
        }
    }
    impl MockA {
        pub fn expect_foo(&mut self)
            -> ::mockall::ExpectationBuilder<<Self as A>::T, <Self as A>::T>
        {
            self.e.expect::<<Self as A>::T, <Self as A>::T>("foo")
        }
    }

    let mut mock = MockA::default();
    mock.expect_foo()
        .returning(|x| x);
    assert_eq!(4, mock.foo(4));
}

#[test]
fn consume_parameters() {
    struct NonCopy{}
    #[mock]
    trait T {
        fn foo(&self, x: NonCopy);
    }

    let mut mock = MockT::default();
    mock.expect_foo()
        .returning(|_x: NonCopy| ());
    mock.foo(NonCopy{});
}

#[test]
fn generic_parameters() {
    #[mock]
    trait A {
        fn foo<T: 'static>(&self, t: T);
    }

    let mut mock = MockA::default();
    mock.expect_foo::<u32>()
        .returning(|_x: u32| ());
    mock.expect_foo::<i16>()
        .returning(|_x: i16| ());
    mock.foo(5u32);
    mock.foo(-1i16);
}

#[test]
fn generic_return() {
    #[mock]
    trait A {
        fn foo<T: 'static>(&self, t: T) -> T;
    }

    let mut mock = MockA::default();
    mock.expect_foo::<u32>()
        .returning(|_x: u32| 42u32);
    mock.expect_foo::<i16>()
        .returning(|_x: i16| 42i16);
    assert_eq!(42u32, mock.foo(5u32));
    assert_eq!(42i16, mock.foo(-1i16));
}

#[test]
#[allow(unused)]
fn generic_struct() {
    #[mock]
    struct GenericStruct<'a, T, V> {
        t: T,
        v: &'a V
    }
    #[mock]
    impl<'a, T, V> GenericStruct<'a, T, V> {
        fn foo(&self, _x: u32) -> i64 {
            42
        }
    }

    let mut mock = MockGenericStruct::<'static, u8, i8>::default();
    mock.expect_foo()
        .returning(|x| i64::from(x) + 1);
    assert_eq!(5, mock.foo(4));
}

#[test]
fn generic_trait() {
    #[mock]
    trait A<T> {
        fn foo(&self);
    }

    let mut mock = MockA::<u32>::default();
    mock.expect_foo()
        .returning(|_| ());
    mock.foo();
}

#[test]
#[allow(unused)]
fn impl_trait() {
    trait Foo {
        fn foo(&self, x: u32) -> i64;
    }

    #[mock]
    struct SomeStruct {}

    #[mock]
    impl Foo for SomeStruct {
        fn foo(&self, _x: u32) -> i64 {
            42
        }
    }

    let mut mock = MockSomeStruct::default();
    mock.expect_foo()
        .returning(|x| i64::from(x) + 1);
    assert_eq!(5, mock.foo(4));
}

// TODO: implement inherited traits
//#[test]
//fn inherited_trait() {
    //#[mock]
    //trait A {
        //fn foo(&self);
    //}
    //#[mock]
    //trait B: A {
        //fn bar(&self);
    //}

    //let mut mock = MockB::default();
    //mock.expect_foo().returning(|| ());
    //mock.expect_bar().returning(|| ());
    //mock.foo();
    //mock.bar();
//}

/// mockall should be able to mock methods with at least 16 arguments
#[test]
#[allow(unused)]
fn many_args() {
    #[mock]
    struct ManyArgs {}
    #[mock]
    impl ManyArgs {
        fn foo(&self, _a0: u8, _a1: u8, _a2: u8, _a3: u8, _a4: u8, _a5: u8,
               _a6: u8, _a7: u8, _a8: u8, _a9: u8, _a10: u8, _a11: u8,
               _a12: u8, _a13: u8, _a14: u8, _a15: u8) {
        }
    }

    let mut mock = MockManyArgs::default();
    mock.expect_foo()
        .returning(|_: (u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8)| ());
    mock.foo(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}

#[test]
#[allow(unused)]
fn method_self_by_value() {
    #[mock]
    struct MethodByValue {}

    #[mock]
    impl MethodByValue {
        fn foo(self, _x: u32) -> i64 {
            42
        }
    }

    let mut mock = MockMethodByValue::default();
    mock.expect_foo()
        .returning(|x| i64::from(x) + 1);
    assert_eq!(5, mock.foo(4));
}

#[test]
#[allow(unused)]
fn multi_trait() {
    trait A {}
    trait B {}
    #[mock]
    struct MultiTrait {}
    #[mock]
    impl A for MultiTrait {}
    #[mock]
    impl B for MultiTrait {}

    fn foo<T: A + B>(_t: T) {}

    let mock = MockMultiTrait::default();
    foo(mock);
}

#[test]
#[allow(unused)]
fn pub_crate_struct() {
    #[mock]
    pub(crate) struct PubStruct {
        x: i16
    }
    #[mock]
    impl PubStruct {
        pub(crate) fn foo(&self, _x: u32) -> i64 {
            42
        }
    }

    let mut mock = MockPubStruct::default();
    mock.expect_foo()
        .returning(|x| i64::from(x) + 1);
    assert_eq!(5, mock.foo(4));
}

#[test]
#[allow(unused)]
fn pub_super_struct() {
    mod m {
        use super::*;
        #[mock]
        pub(super) struct PubStruct {
            x: i16
        }
        #[mock]
        impl PubStruct {
            pub(super) fn foo(&self, _x: u32) -> i64 {
                42
            }
        }
    }

    let mut mock = m::MockPubStruct::default();
    mock.expect_foo()
        .returning(|x| i64::from(x) + 1);
    assert_eq!(5, mock.foo(4));
}

#[test]
#[allow(unused)]
fn pub_struct() {
    #[mock]
    pub struct PubStruct {
        x: i16
    }
    #[mock]
    impl PubStruct {
        pub fn foo(&self, _x: u32) -> i64 {
            42
        }
    }

    let mut mock = MockPubStruct::default();
    mock.expect_foo()
        .returning(|x| i64::from(x) + 1);
    assert_eq!(5, mock.foo(4));
}

#[test]
#[allow(unused)]
fn simple_struct() {
    #[mock]
    struct SimpleStruct {
        x: i16
    }
    #[mock]
    impl SimpleStruct {
        fn foo(&self, _x: u32) -> i64 {
            42
        }
    }

    let mut mock = MockSimpleStruct::default();
    mock.expect_foo()
        .returning(|x| i64::from(x) + 1);
    assert_eq!(5, mock.foo(4));
}

#[test]
fn simple_trait() {
    #[mock]
    trait SimpleTrait {
        fn foo(&self, x: u32) -> u32;
    }

    let mut mock = MockSimpleTrait::default();
    mock.expect_foo()
        .returning(|x| x + 1);
    assert_eq!(5, mock.foo(4));
}
<commit_msg>mockall_derive: add a test for returning non-'static lifetimes<commit_after>// vim: tw=80

use mockall;
use mockall_derive::mock;
use std::default::Default;

/// Mocking a trait with associated types currently requires manual mocking.
/// TODO: add derive support for this, perhaps by providing the "type T=u32" as
/// an attr argument to mock.
#[test]
fn associated_types() {
    trait A {
        type T;
        fn foo(&self, x: Self::T) -> Self::T;
    }

    #[derive(Default)]
    struct MockA {
        e: ::mockall::Expectations,
    }
    impl A for MockA {
        type T=u32;

        fn foo(&self, x: Self::T) -> Self::T {
            self.e.called::<Self::T, Self::T>("foo", x)
        }
    }
    impl MockA {
        pub fn expect_foo(&mut self)
            -> ::mockall::ExpectationBuilder<<Self as A>::T, <Self as A>::T>
        {
            self.e.expect::<<Self as A>::T, <Self as A>::T>("foo")
        }
    }

    let mut mock = MockA::default();
    mock.expect_foo()
        .returning(|x| x);
    assert_eq!(4, mock.foo(4));
}

#[test]
fn consume_parameters() {
    struct NonCopy{}
    #[mock]
    trait T {
        fn foo(&self, x: NonCopy);
    }

    let mut mock = MockT::default();
    mock.expect_foo()
        .returning(|_x: NonCopy| ());
    mock.foo(NonCopy{});
}

#[test]
fn generic_parameters() {
    #[mock]
    trait A {
        fn foo<T: 'static>(&self, t: T);
    }

    let mut mock = MockA::default();
    mock.expect_foo::<u32>()
        .returning(|_x: u32| ());
    mock.expect_foo::<i16>()
        .returning(|_x: i16| ());
    mock.foo(5u32);
    mock.foo(-1i16);
}

#[test]
fn generic_return() {
    #[mock]
    trait A {
        fn foo<T: 'static>(&self, t: T) -> T;
    }

    let mut mock = MockA::default();
    mock.expect_foo::<u32>()
        .returning(|_x: u32| 42u32);
    mock.expect_foo::<i16>()
        .returning(|_x: i16| 42i16);
    assert_eq!(42u32, mock.foo(5u32));
    assert_eq!(42i16, mock.foo(-1i16));
}

#[test]
#[allow(unused)]
fn generic_struct() {
    #[mock]
    struct GenericStruct<'a, T, V> {
        t: T,
        v: &'a V
    }
    #[mock]
    impl<'a, T, V> GenericStruct<'a, T, V> {
        fn foo(&self, _x: u32) -> i64 {
            42
        }
    }

    let mut mock = MockGenericStruct::<'static, u8, i8>::default();
    mock.expect_foo()
        .returning(|x| i64::from(x) + 1);
    assert_eq!(5, mock.foo(4));
}

#[test]
fn generic_trait() {
    #[mock]
    trait A<T> {
        fn foo(&self);
    }

    let mut mock = MockA::<u32>::default();
    mock.expect_foo()
        .returning(|_| ());
    mock.foo();
}

#[test]
#[allow(unused)]
fn impl_trait() {
    trait Foo {
        fn foo(&self, x: u32) -> i64;
    }

    #[mock]
    struct SomeStruct {}

    #[mock]
    impl Foo for SomeStruct {
        fn foo(&self, _x: u32) -> i64 {
            42
        }
    }

    let mut mock = MockSomeStruct::default();
    mock.expect_foo()
        .returning(|x| i64::from(x) + 1);
    assert_eq!(5, mock.foo(4));
}

// TODO: implement inherited traits
//#[test]
//fn inherited_trait() {
    //#[mock]
    //trait A {
        //fn foo(&self);
    //}
    //#[mock]
    //trait B: A {
        //fn bar(&self);
    //}

    //let mut mock = MockB::default();
    //mock.expect_foo().returning(|| ());
    //mock.expect_bar().returning(|| ());
    //mock.foo();
    //mock.bar();
//}

/// mockall should be able to mock methods with at least 16 arguments
#[test]
#[allow(unused)]
fn many_args() {
    #[mock]
    struct ManyArgs {}
    #[mock]
    impl ManyArgs {
        fn foo(&self, _a0: u8, _a1: u8, _a2: u8, _a3: u8, _a4: u8, _a5: u8,
               _a6: u8, _a7: u8, _a8: u8, _a9: u8, _a10: u8, _a11: u8,
               _a12: u8, _a13: u8, _a14: u8, _a15: u8) {
        }
    }

    let mut mock = MockManyArgs::default();
    mock.expect_foo()
        .returning(|_: (u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8)| ());
    mock.foo(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}

#[test]
#[allow(unused)]
fn method_self_by_value() {
    #[mock]
    struct MethodByValue {}

    #[mock]
    impl MethodByValue {
        fn foo(self, _x: u32) -> i64 {
            42
        }
    }

    let mut mock = MockMethodByValue::default();
    mock.expect_foo()
        .returning(|x| i64::from(x) + 1);
    assert_eq!(5, mock.foo(4));
}

#[test]
#[allow(unused)]
fn multi_trait() {
    trait A {}
    trait B {}
    #[mock]
    struct MultiTrait {}
    #[mock]
    impl A for MultiTrait {}
    #[mock]
    impl B for MultiTrait {}

    fn foo<T: A + B>(_t: T) {}

    let mock = MockMultiTrait::default();
    foo(mock);
}

#[test]
#[allow(unused)]
fn pub_crate_struct() {
    #[mock]
    pub(crate) struct PubStruct {
        x: i16
    }
    #[mock]
    impl PubStruct {
        pub(crate) fn foo(&self, _x: u32) -> i64 {
            42
        }
    }

    let mut mock = MockPubStruct::default();
    mock.expect_foo()
        .returning(|x| i64::from(x) + 1);
    assert_eq!(5, mock.foo(4));
}

#[test]
#[allow(unused)]
fn pub_super_struct() {
    mod m {
        use super::*;
        #[mock]
        pub(super) struct PubStruct {
            x: i16
        }
        #[mock]
        impl PubStruct {
            pub(super) fn foo(&self, _x: u32) -> i64 {
                42
            }
        }
    }

    let mut mock = m::MockPubStruct::default();
    mock.expect_foo()
        .returning(|x| i64::from(x) + 1);
    assert_eq!(5, mock.foo(4));
}

#[test]
#[allow(unused)]
fn pub_struct() {
    #[mock]
    pub struct PubStruct {
        x: i16
    }
    #[mock]
    impl PubStruct {
        pub fn foo(&self, _x: u32) -> i64 {
            42
        }
    }

    let mut mock = MockPubStruct::default();
    mock.expect_foo()
        .returning(|x| i64::from(x) + 1);
    assert_eq!(5, mock.foo(4));
}

// TODO: mock non-'static lifetimes
//#[test]
//fn return_lifetime() {
    //#[mock]
    //trait A<'a> {
        //fn foo(&'a self) -> &'a u32;
    //}

    //let mut mock = MockA::<'static>::default();
    //mock.expect_foo()
        //.returning(|_| &5);
    //assert_eq!(5, *mock.foo());
//}

#[test]
#[allow(unused)]
fn simple_struct() {
    #[mock]
    struct SimpleStruct {
        x: i16
    }
    #[mock]
    impl SimpleStruct {
        fn foo(&self, _x: u32) -> i64 {
            42
        }
    }

    let mut mock = MockSimpleStruct::default();
    mock.expect_foo()
        .returning(|x| i64::from(x) + 1);
    assert_eq!(5, mock.foo(4));
}

#[test]
fn simple_trait() {
    #[mock]
    trait SimpleTrait {
        fn foo(&self, x: u32) -> u32;
    }

    let mut mock = MockSimpleTrait::default();
    mock.expect_foo()
        .returning(|x| x + 1);
    assert_eq!(5, mock.foo(4));
}
<|endoftext|>


<commit_before>// Copyright 2016 The xi-editor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate log;
extern crate chrono;
extern crate fern;

extern crate dirs;

extern crate xi_core_lib;
extern crate xi_rpc;

use std::collections::HashMap;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

use xi_core_lib::XiCore;
use xi_rpc::RpcLoop;

const XI_LOG_DIR: &str = "xi-core";
const XI_LOG_FILE: &str = "xi-core.log";

fn get_logging_directory_path<P: AsRef<Path>>(directory: P) -> Result<PathBuf, io::Error> {
    match dirs::data_local_dir() {
        Some(mut log_dir) => {
            log_dir.push(directory);
            Ok(log_dir)
        }
        None => Err(
            io::Error::new(
                io::ErrorKind::NotFound,
                "No standard logging directory known for this platform",
            )
        ),
    }
}

fn setup_logging(logging_path_result: Result<PathBuf, io::Error>) -> Result<(), fern::InitError> {
    let level_filter = match std::env::var("XI_LOG") {
        Ok(level) => match level.to_lowercase().as_ref() {
            "trace" => log::LevelFilter::Trace,
            "debug" => log::LevelFilter::Debug,
            _ => log::LevelFilter::Info,
        },
        // Default to info
        Err(_) => log::LevelFilter::Info,
    };

    let mut fern_dispatch = 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(level_filter)
        .chain(io::stderr());

    if let Ok(logging_file_path) = &logging_path_result {
        // Ensure the logging directory is created
        let parent_path = logging_file_path.parent().ok_or(
            io::Error::new(
                io::ErrorKind::InvalidInput,
                format!(
                    "Unable to get the parent of the following Path: {}", logging_file_path.display(),
                )
            )
        )?;
        fs::create_dir_all(parent_path)?;
        // Attach it to fern
        fern_dispatch = fern_dispatch.chain(fern::log_file(logging_file_path)?);
    };

    // Start fern
    fern_dispatch.apply()?;

    // Log details of the fern setup using fern/log
    match &path_result {
        Err(e) => {
            let message = "There was an issue getting the path for the log file";
            warn!("{}: {:?}, falling back to stderr.", message, e);
        }
        Ok(logging_file_path) => info!("Logging to the following file: {:?}", logging_file_path),
    }

    info!("Logging with fern is setup");
    Ok(())
}

fn prepare_logging_path(logfile_config: LogfileConfig) -> Result<PathBuf, io::Error> {
    // Use the file name set in logfile_config or fallback to the default
    let logfile_file_name = match logfile_config.file {
        Some(file_name) => file_name,
        None => XI_LOG_FILE.to_string(),
    };
    // Use the directory name set in logfile_config or fallback to the default
    let logfile_directory_name = match logfile_config.directory {
        Some(dir) => dir,
        None => XI_LOG_DIR.to_string(),
    };

    let mut logging_directory_path = get_logging_directory_path(logfile_directory_name)?;

    // Add the file name & return the full path
    logging_directory_path.push(logfile_file_name);
    Ok(logging_directory_path)
}

struct LogfileConfig {
    directory: Option<String>,
    file: Option<String>,
}

fn get_flags() -> HashMap<String, Option<String>> {
    let mut flags: HashMap<String, Option<String>> = HashMap::new();

    let flag_prefix = "-";
    let mut args_itterator = std::env::args().peekable();
    while let Some(arg) = args_itterator.next() {
        if arg.starts_with(flag_prefix) {
            let key = arg.trim_left_matches(flag_prefix).to_string();

            // Check the next argument doesn't start with the flag prefix
            // map_or accounts for peek returning an Option
            let next_arg_not_a_flag: bool = args_itterator.peek().map_or(false, |val| !val.starts_with(flag_prefix));
            if next_arg_not_a_flag {
                flags.insert(key, args_itterator.next());
            }
        }
    }
    flags
}

fn main() {
    let mut state = XiCore::new();
    let stdin = io::stdin();
    let stdout = io::stdout();
    let mut rpc_looper = RpcLoop::new(stdout);

    let flags: HashMap<String, Option<String>> = get_flags();

    // If the key is set, get the Option within
    let log_dir_flag_option = flags.get("log-dir").cloned().unwrap_or(None);
    let log_file_flag_option = flags.get("log-file").cloned().unwrap_or(None);

    let logfile_config = LogfileConfig {
        directory: log_dir_flag_option,
        file: log_file_flag_option,
    };

    let logging_path: Result<PathBuf, io::Error> = prepare_logging_path(logfile_config);
    if let Err(e) = setup_logging(logging_path) {
        eprintln!(
            "[ERROR] setup_logging returned error, logging disabled: {:?}",
            e
        );
    }

    match rpc_looper.mainloop(|| stdin.lock(), &mut state) {
        Ok(_) => (),
        Err(err) => error!("xi-core exited with error:\n{:?}", err),
    }
}
<commit_msg>Moved the first info log up. Made the success logging clearer.<commit_after>// Copyright 2016 The xi-editor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate log;
extern crate chrono;
extern crate fern;

extern crate dirs;

extern crate xi_core_lib;
extern crate xi_rpc;

use std::collections::HashMap;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

use xi_core_lib::XiCore;
use xi_rpc::RpcLoop;

const XI_LOG_DIR: &str = "xi-core";
const XI_LOG_FILE: &str = "xi-core.log";

fn get_logging_directory_path<P: AsRef<Path>>(directory: P) -> Result<PathBuf, io::Error> {
    match dirs::data_local_dir() {
        Some(mut log_dir) => {
            log_dir.push(directory);
            Ok(log_dir)
        }
        None => Err(
            io::Error::new(
                io::ErrorKind::NotFound,
                "No standard logging directory known for this platform",
            )
        ),
    }
}

fn setup_logging(logging_path_result: Result<PathBuf, io::Error>) -> Result<(), fern::InitError> {
    let level_filter = match std::env::var("XI_LOG") {
        Ok(level) => match level.to_lowercase().as_ref() {
            "trace" => log::LevelFilter::Trace,
            "debug" => log::LevelFilter::Debug,
            _ => log::LevelFilter::Info,
        },
        // Default to info
        Err(_) => log::LevelFilter::Info,
    };

    let mut fern_dispatch = 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(level_filter)
        .chain(io::stderr());

    if let Ok(logging_file_path) = &logging_path_result {
        // Ensure the logging directory is created
        let parent_path = logging_file_path.parent().ok_or(
            io::Error::new(
                io::ErrorKind::InvalidInput,
                format!(
                    "Unable to get the parent of the following Path: {}", logging_file_path.display(),
                )
            )
        )?;
        fs::create_dir_all(parent_path)?;
        // Attach it to fern
        fern_dispatch = fern_dispatch.chain(fern::log_file(logging_file_path)?);
    };

    // Start fern
    fern_dispatch.apply()?;
    info!("Logging with fern is setup");

    // Log details of the logging_file_path result using fern/log
    // Either logging the path fern is outputting to or the error from obtaining the path
    match &logging_path_result {
        Err(e) => {
            let message = "There was an issue getting the path for the log file";
            warn!("{}: {:?}, falling back to stderr.", message, e);
        }
        Ok(logging_file_path) => {
            info!("Logging to the following file: {}", logging_file_path.display());
        }
    }
    Ok(())
}

fn prepare_logging_path(logfile_config: LogfileConfig) -> Result<PathBuf, io::Error> {
    // Use the file name set in logfile_config or fallback to the default
    let logfile_file_name = match logfile_config.file {
        Some(file_name) => file_name,
        None => XI_LOG_FILE.to_string(),
    };
    // Use the directory name set in logfile_config or fallback to the default
    let logfile_directory_name = match logfile_config.directory {
        Some(dir) => dir,
        None => XI_LOG_DIR.to_string(),
    };

    let mut logging_directory_path = get_logging_directory_path(logfile_directory_name)?;

    // Add the file name & return the full path
    logging_directory_path.push(logfile_file_name);
    Ok(logging_directory_path)
}

struct LogfileConfig {
    directory: Option<String>,
    file: Option<String>,
}

fn get_flags() -> HashMap<String, Option<String>> {
    let mut flags: HashMap<String, Option<String>> = HashMap::new();

    let flag_prefix = "-";
    let mut args_itterator = std::env::args().peekable();
    while let Some(arg) = args_itterator.next() {
        if arg.starts_with(flag_prefix) {
            let key = arg.trim_left_matches(flag_prefix).to_string();

            // Check the next argument doesn't start with the flag prefix
            // map_or accounts for peek returning an Option
            let next_arg_not_a_flag: bool = args_itterator.peek().map_or(false, |val| !val.starts_with(flag_prefix));
            if next_arg_not_a_flag {
                flags.insert(key, args_itterator.next());
            }
        }
    }
    flags
}

fn main() {
    let mut state = XiCore::new();
    let stdin = io::stdin();
    let stdout = io::stdout();
    let mut rpc_looper = RpcLoop::new(stdout);

    let flags: HashMap<String, Option<String>> = get_flags();

    // If the key is set, get the Option within
    let log_dir_flag_option = flags.get("log-dir").cloned().unwrap_or(None);
    let log_file_flag_option = flags.get("log-file").cloned().unwrap_or(None);

    let logfile_config = LogfileConfig {
        directory: log_dir_flag_option,
        file: log_file_flag_option,
    };

    let logging_path: Result<PathBuf, io::Error> = prepare_logging_path(logfile_config);
    if let Err(e) = setup_logging(logging_path) {
        eprintln!(
            "[ERROR] setup_logging returned error, logging disabled: {:?}",
            e
        );
    }

    match rpc_looper.mainloop(|| stdin.lock(), &mut state) {
        Ok(_) => (),
        Err(err) => error!("xi-core exited with error:\n{:?}", err),
    }
}
<|endoftext|>


<commit_before>extern crate sdl2;

use std::path::Path;
use sdl2::surface::{Surface};

fn main() {
    let ctx = sdl2::init().unwrap();
    let video_ctx = ctx.video().unwrap();
    let mut timer = ctx.timer().unwrap();

    // Create a new OpenGL window
    let window  = match video_ctx.window("Hello World!", 960, 540).position_centered().opengl().build() {
        Ok(window) => window,
        Err(err)   => panic!("failed to create window: {}", err)
    };

    // Load the image as a surface
    let surface = match Surface::load_bmp(&Path::new("../img/boxes.bmp")) {
        Ok(surface) => surface,
        Err(err)    => panic!("failed to load surface: {}", err)
    };

    {
        {
            // Get the window surface
            let events = ctx.event_pump().unwrap();
            let screen = window.surface(&events).unwrap();

            // Blit the image to the window
            unsafe {
                let _ = surface.blit(None, Surface::from_ll(screen.raw()), None);
            }
        }

        for _ in 0..20 {

            // Update the window to display the changed surface
            match window.update_surface() {
                Ok(_) => {},
                Err(err) => panic!("failed to update window surface: {}", err)
            }

            // Wait 100ms
            timer.delay(100);
        }
    }

}
<commit_msg>update rust example because of library changes<commit_after>extern crate sdl2;

use std::path::Path;
use sdl2::surface::{Surface};

fn main() {
    let ctx = sdl2::init().unwrap();
    let video_ctx = ctx.video().unwrap();
    let mut timer = ctx.timer().unwrap();

    // Create a new OpenGL window
    let mut window  = match video_ctx.window("Hello World!", 960, 540).position_centered().opengl().build() {
        Ok(window) => window,
        Err(err)   => panic!("failed to create window: {}", err)
    };

    // Load the image as a surface
    let surface = match Surface::load_bmp(&Path::new("../img/boxes.bmp")) {
        Ok(surface) => surface,
        Err(err)    => panic!("failed to load surface: {}", err)
    };

    {
        {
            // Get the window surface
            let events = ctx.event_pump().unwrap();
            let screen = window.surface_mut(&events).unwrap();

            // Blit the image to the window
            unsafe {
                let _ = surface.blit(None, screen, None);
            }
        }

        for _ in 0..20 {

            // Update the window to display the changed surface
            match window.update_surface() {
                Ok(_) => {},
                Err(err) => panic!("failed to update window surface: {}", err)
            }

            // Wait 100ms
            timer.delay(100);
        }
    }

}
<|endoftext|>


<commit_before>use std::io::Command;
use std::io::process::StdioContainer;
#[cfg(target_os = "linux")]
use std::io::fs;

#[cfg(target_os = "linux")]
fn main() {
    Command::new("make")
            .arg("-C").arg("modules/oculus_sdk_linux/")
            .status()
            .stdout(StdioContainer::InheritFd(1))
            .stderr(StdioContainer::InheritFd(2))
            .ok().expect("Failed to build");
    fs::copy(&Path::new("modules/oculus_sdk_linux/LibOVR/Lib/Linux/Release/x86_64/libovr.a"),
             &Path::new(env!("OUT_DIR")).join(Path::new("libovr.a")))
            .ok().expect("Failed to move file");

    println!("cargo:rustc-flags=-L {} -l ovr:static", env!("OUT_DIR"));
}

#[cfg(target_os = "macos")]
fn main() {
    Command::new("xcodebuild")
            .arg("-project")
            .arg("modules/oculus_sdk_mac/LibOVR/Projects/Mac/Xcode/LibOVR.xcodeproj")
            .arg("build")
            .stdout(StdioContainer::InheritFd(1))
            .stderr(StdioContainer::InheritFd(2))
            .status()
            .ok().expect("Failed to build");
    Command::new("lipo")
            .arg("modules/oculus_sdk_mac/LibOVR/Lib/MacOS/Release/libovr.a")
            .arg("-thin")
            .arg("x86_64")
            .arg("-output")
            .arg(Path::new(env!("OUT_DIR")).join(Path::new("libovr.a")).as_str().unwrap())
            .stdout(StdioContainer::InheritFd(1))
            .stderr(StdioContainer::InheritFd(2))
            .status()
            .ok().expect("Failed to lipo library");
    println!("cargo:rustc-flags=-L {} -l ovr:static", env!("OUT_DIR"));
}<commit_msg>Fix linux build<commit_after>use std::io::Command;
use std::io::process::StdioContainer;
#[cfg(target_os = "linux")]
use std::io::fs;

#[cfg(target_os = "linux")]
fn main() {
    Command::new("make")
            .arg("-C").arg("modules/oculus_sdk_linux/")
            .stdout(StdioContainer::InheritFd(1))
            .stderr(StdioContainer::InheritFd(2))
            .status()
            .ok().expect("Failed to build");
    fs::copy(&Path::new("modules/oculus_sdk_linux/LibOVR/Lib/Linux/Release/x86_64/libovr.a"),
             &Path::new(env!("OUT_DIR")).join(Path::new("libovr.a")))
            .ok().expect("Failed to move file");

    println!("cargo:rustc-flags=-L {} -l ovr:static", env!("OUT_DIR"));
}

#[cfg(target_os = "macos")]
fn main() {
    Command::new("xcodebuild")
            .arg("-project")
            .arg("modules/oculus_sdk_mac/LibOVR/Projects/Mac/Xcode/LibOVR.xcodeproj")
            .arg("build")
            .stdout(StdioContainer::InheritFd(1))
            .stderr(StdioContainer::InheritFd(2))
            .status()
            .ok().expect("Failed to build");
    Command::new("lipo")
            .arg("modules/oculus_sdk_mac/LibOVR/Lib/MacOS/Release/libovr.a")
            .arg("-thin")
            .arg("x86_64")
            .arg("-output")
            .arg(Path::new(env!("OUT_DIR")).join(Path::new("libovr.a")).as_str().unwrap())
            .stdout(StdioContainer::InheritFd(1))
            .stderr(StdioContainer::InheritFd(2))
            .status()
            .ok().expect("Failed to lipo library");
    println!("cargo:rustc-flags=-L {} -l ovr:static", env!("OUT_DIR"));
}<|endoftext|>


<commit_before>use int::Int;

macro_rules! div {
    ($intrinsic:ident: $ty:ty, $uty:ty) => {
        div!($intrinsic: $ty, $uty, $ty, |i| {i});
    };
    ($intrinsic:ident: $ty:ty, $uty:ty, $tyret:ty, $conv:expr) => {
        /// Returns `a / b`
        #[cfg_attr(not(test), no_mangle)]
        pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $tyret {
            let s_a = a >> (<$ty>::bits() - 1);
            let s_b = b >> (<$ty>::bits() - 1);
            // NOTE it's OK to overflow here because of the `as $uty` cast below
            // This whole operation is computing the absolute value of the inputs
            // So some overflow will happen when dealing with e.g. `i64::MIN`
            // where the absolute value is `(-i64::MIN) as u64`
            let a = (a ^ s_a).wrapping_sub(s_a);
            let b = (b ^ s_b).wrapping_sub(s_b);
            let s = s_a ^ s_b;

            let r = udiv!(a as $uty, b as $uty);
            ($conv)((r as $ty ^ s) - s)
        }
    }
}

macro_rules! mod_ {
    ($intrinsic:ident: $ty:ty, $uty:ty) => {
        mod_!($intrinsic: $ty, $uty, $ty, |i| {i});
    };
    ($intrinsic:ident: $ty:ty, $uty:ty, $tyret:ty, $conv:expr) => {
        /// Returns `a % b`
        #[cfg_attr(not(test), no_mangle)]
        pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $tyret {
            let s = b >> (<$ty>::bits() - 1);
            let b = (b ^ s) - s;
            let s = a >> (<$ty>::bits() - 1);
            let a = (a ^ s) - s;

            let r = urem!(a as $uty, b as $uty);
            ($conv)((r as $ty ^ s) - s)
        }
    }
}

macro_rules! divmod {
    ($abi:tt, $intrinsic:ident, $div:ident: $ty:ty) => {
        /// Returns `a / b` and sets `*rem = n % d`
        #[cfg_attr(not(test), no_mangle)]
        pub extern $abi fn $intrinsic(a: $ty, b: $ty, rem: &mut $ty) -> $ty {
            #[cfg(all(feature = "c", any(target_arch = "x86")))]
            extern {
                fn $div(a: $ty, b: $ty) -> $ty;
            }

            let r = match () {
                #[cfg(not(all(feature = "c", any(target_arch = "x86"))))]
                () => $div(a, b),
                #[cfg(all(feature = "c", any(target_arch = "x86")))]
                () => unsafe { $div(a, b) },
            };
            // NOTE won't overflow because it's using the result from the
            // previous division
            *rem = a - r.wrapping_mul(b);
            r
        }
    }
}

#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))]
div!(__divsi3: i32, u32);

#[cfg(not(all(feature = "c", target_arch = "x86")))]
div!(__divdi3: i64, u64);

#[cfg(not(all(windows, target_pointer_width="64")))]
div!(__divti3: i128, u128);

#[cfg(all(windows, target_pointer_width="64"))]
div!(__divti3: i128, u128, ::U64x2, ::sconv);

#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"))))]
mod_!(__modsi3: i32, u32);

#[cfg(not(all(feature = "c", target_arch = "x86")))]
mod_!(__moddi3: i64, u64);

#[cfg(not(all(windows, target_pointer_width="64")))]
mod_!(__modti3: i128, u128);

#[cfg(all(windows, target_pointer_width="64"))]
mod_!(__modti3: i128, u128, ::U64x2, ::sconv);

#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"))))]
divmod!("C", __divmodsi4, __divsi3: i32);

#[cfg(target_arch = "arm")]
divmod!("aapcs", __divmoddi4, __divdi3: i64);

#[cfg(not(target_arch = "arm"))]
divmod!("C", __divmoddi4, __divdi3: i64);

#[cfg(test)]
mod tests {
    use qc::{U32, U64};

    check! {
        fn __divdi3(f: extern "C" fn(i64, i64) -> i64, n: U64, d: U64) -> Option<i64> {
            let (n, d) = (n.0 as i64, d.0 as i64);
            if d == 0 {
                None
            } else {
                Some(f(n, d))
            }
        }

        fn __moddi3(f: extern "C" fn(i64, i64) -> i64, n: U64, d: U64) -> Option<i64> {
            let (n, d) = (n.0 as i64, d.0 as i64);
            if d == 0 {
                None
            } else {
                Some(f(n, d))
            }
        }

        #[cfg(target_arch = "arm")]
        fn __divmoddi4(f: extern "aapcs" fn(i64, i64, &mut i64) -> i64,
                       n: U64,
                       d: U64) -> Option<(i64, i64)> {
            let (n, d) = (n.0 as i64, d.0 as i64);
            if d == 0 {
                None
            } else {
                let mut r = 0;
                let q = f(n, d, &mut r);
                Some((q, r))
            }
        }

        #[cfg(not(target_arch = "arm"))]
        fn __divmoddi4(f: extern "C" fn(i64, i64, &mut i64) -> i64,
                       n: U64,
                       d: U64) -> Option<(i64, i64)> {
            let (n, d) = (n.0 as i64, d.0 as i64);
            if d == 0 {
                None
            } else {
                let mut r = 0;
                let q = f(n, d, &mut r);
                Some((q, r))
            }
        }

        fn __divsi3(f: extern "C" fn(i32, i32) -> i32,
                    n: U32,
                    d: U32) -> Option<i32> {
            let (n, d) = (n.0 as i32, d.0 as i32);
            if d == 0 {
                None
            } else {
                Some(f(n, d))
            }
        }

        fn __modsi3(f: extern "C" fn(i32, i32) -> i32,
                    n: U32,
                    d: U32) -> Option<i32> {
            let (n, d) = (n.0 as i32, d.0 as i32);
            if d == 0 {
                None
            } else {
                Some(f(n, d))
            }
        }

        fn __divmodsi4(f: extern "C" fn(i32, i32, &mut i32) -> i32,
                       n: U32,
                       d: U32) -> Option<(i32, i32)> {
            let (n, d) = (n.0 as i32, d.0 as i32);
            if d == 0 {
                None
            } else {
                let mut r = 0;
                let q = f(n, d, &mut r);
                Some((q, r))
            }
        }
    }
}

#[cfg(test)]
#[cfg(all(not(windows),
          not(target_arch = "mips64"),
          not(target_arch = "mips64el"),
          target_pointer_width="64"))]
mod tests_i128 {
    use qc::U128;
    check! {

        fn __divti3(f: extern "C" fn(i128, i128) -> i128, n: U128, d: U128) -> Option<i128> {
            let (n, d) = (n.0 as i128, d.0 as i128);
            if d == 0 {
                None
            } else {
                Some(f(n, d))
            }
        }

        fn __modti3(f: extern "C" fn(i128, i128) -> i128, n: U128, d: U128) -> Option<i128> {
            let (n, d) = (n.0 as i128, d.0 as i128);
            if d == 0 {
                None
            } else {
                Some(f(n, d))
            }
        }
    }
}
<commit_msg>fix debug assertion in modsi3 / moddi3<commit_after>use int::Int;

macro_rules! div {
    ($intrinsic:ident: $ty:ty, $uty:ty) => {
        div!($intrinsic: $ty, $uty, $ty, |i| {i});
    };
    ($intrinsic:ident: $ty:ty, $uty:ty, $tyret:ty, $conv:expr) => {
        /// Returns `a / b`
        #[cfg_attr(not(test), no_mangle)]
        pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $tyret {
            let s_a = a >> (<$ty>::bits() - 1);
            let s_b = b >> (<$ty>::bits() - 1);
            // NOTE it's OK to overflow here because of the `as $uty` cast below
            // This whole operation is computing the absolute value of the inputs
            // So some overflow will happen when dealing with e.g. `i64::MIN`
            // where the absolute value is `(-i64::MIN) as u64`
            let a = (a ^ s_a).wrapping_sub(s_a);
            let b = (b ^ s_b).wrapping_sub(s_b);
            let s = s_a ^ s_b;

            let r = udiv!(a as $uty, b as $uty);
            ($conv)((r as $ty ^ s) - s)
        }
    }
}

macro_rules! mod_ {
    ($intrinsic:ident: $ty:ty, $uty:ty) => {
        mod_!($intrinsic: $ty, $uty, $ty, |i| {i});
    };
    ($intrinsic:ident: $ty:ty, $uty:ty, $tyret:ty, $conv:expr) => {
        /// Returns `a % b`
        #[cfg_attr(not(test), no_mangle)]
        pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $tyret {
            let s = b >> (<$ty>::bits() - 1);
            // NOTE(wrapping_sub) see comment in the `div` macro
            let b = (b ^ s).wrapping_sub(s);
            let s = a >> (<$ty>::bits() - 1);
            let a = (a ^ s).wrapping_sub(s);

            let r = urem!(a as $uty, b as $uty);
            ($conv)((r as $ty ^ s) - s)
        }
    }
}

macro_rules! divmod {
    ($abi:tt, $intrinsic:ident, $div:ident: $ty:ty) => {
        /// Returns `a / b` and sets `*rem = n % d`
        #[cfg_attr(not(test), no_mangle)]
        pub extern $abi fn $intrinsic(a: $ty, b: $ty, rem: &mut $ty) -> $ty {
            #[cfg(all(feature = "c", any(target_arch = "x86")))]
            extern {
                fn $div(a: $ty, b: $ty) -> $ty;
            }

            let r = match () {
                #[cfg(not(all(feature = "c", any(target_arch = "x86"))))]
                () => $div(a, b),
                #[cfg(all(feature = "c", any(target_arch = "x86")))]
                () => unsafe { $div(a, b) },
            };
            // NOTE won't overflow because it's using the result from the
            // previous division
            *rem = a - r.wrapping_mul(b);
            r
        }
    }
}

#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"), not(thumbv6m))))]
div!(__divsi3: i32, u32);

#[cfg(not(all(feature = "c", target_arch = "x86")))]
div!(__divdi3: i64, u64);

#[cfg(not(all(windows, target_pointer_width="64")))]
div!(__divti3: i128, u128);

#[cfg(all(windows, target_pointer_width="64"))]
div!(__divti3: i128, u128, ::U64x2, ::sconv);

#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"))))]
mod_!(__modsi3: i32, u32);

#[cfg(not(all(feature = "c", target_arch = "x86")))]
mod_!(__moddi3: i64, u64);

#[cfg(not(all(windows, target_pointer_width="64")))]
mod_!(__modti3: i128, u128);

#[cfg(all(windows, target_pointer_width="64"))]
mod_!(__modti3: i128, u128, ::U64x2, ::sconv);

#[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"))))]
divmod!("C", __divmodsi4, __divsi3: i32);

#[cfg(target_arch = "arm")]
divmod!("aapcs", __divmoddi4, __divdi3: i64);

#[cfg(not(target_arch = "arm"))]
divmod!("C", __divmoddi4, __divdi3: i64);

#[cfg(test)]
mod tests {
    use qc::{U32, U64};

    check! {
        fn __divdi3(f: extern "C" fn(i64, i64) -> i64, n: U64, d: U64) -> Option<i64> {
            let (n, d) = (n.0 as i64, d.0 as i64);
            if d == 0 {
                None
            } else {
                Some(f(n, d))
            }
        }

        fn __moddi3(f: extern "C" fn(i64, i64) -> i64, n: U64, d: U64) -> Option<i64> {
            let (n, d) = (n.0 as i64, d.0 as i64);
            if d == 0 {
                None
            } else {
                Some(f(n, d))
            }
        }

        #[cfg(target_arch = "arm")]
        fn __divmoddi4(f: extern "aapcs" fn(i64, i64, &mut i64) -> i64,
                       n: U64,
                       d: U64) -> Option<(i64, i64)> {
            let (n, d) = (n.0 as i64, d.0 as i64);
            if d == 0 {
                None
            } else {
                let mut r = 0;
                let q = f(n, d, &mut r);
                Some((q, r))
            }
        }

        #[cfg(not(target_arch = "arm"))]
        fn __divmoddi4(f: extern "C" fn(i64, i64, &mut i64) -> i64,
                       n: U64,
                       d: U64) -> Option<(i64, i64)> {
            let (n, d) = (n.0 as i64, d.0 as i64);
            if d == 0 {
                None
            } else {
                let mut r = 0;
                let q = f(n, d, &mut r);
                Some((q, r))
            }
        }

        fn __divsi3(f: extern "C" fn(i32, i32) -> i32,
                    n: U32,
                    d: U32) -> Option<i32> {
            let (n, d) = (n.0 as i32, d.0 as i32);
            if d == 0 {
                None
            } else {
                Some(f(n, d))
            }
        }

        fn __modsi3(f: extern "C" fn(i32, i32) -> i32,
                    n: U32,
                    d: U32) -> Option<i32> {
            let (n, d) = (n.0 as i32, d.0 as i32);
            if d == 0 {
                None
            } else {
                Some(f(n, d))
            }
        }

        fn __divmodsi4(f: extern "C" fn(i32, i32, &mut i32) -> i32,
                       n: U32,
                       d: U32) -> Option<(i32, i32)> {
            let (n, d) = (n.0 as i32, d.0 as i32);
            if d == 0 {
                None
            } else {
                let mut r = 0;
                let q = f(n, d, &mut r);
                Some((q, r))
            }
        }
    }
}

#[cfg(test)]
#[cfg(all(not(windows),
          not(target_arch = "mips64"),
          not(target_arch = "mips64el"),
          target_pointer_width="64"))]
mod tests_i128 {
    use qc::U128;
    check! {

        fn __divti3(f: extern "C" fn(i128, i128) -> i128, n: U128, d: U128) -> Option<i128> {
            let (n, d) = (n.0 as i128, d.0 as i128);
            if d == 0 {
                None
            } else {
                Some(f(n, d))
            }
        }

        fn __modti3(f: extern "C" fn(i128, i128) -> i128, n: U128, d: U128) -> Option<i128> {
            let (n, d) = (n.0 as i128, d.0 as i128);
            if d == 0 {
                None
            } else {
                Some(f(n, d))
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.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.

//! # Serde
//!
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
//! structures efficiently and generically.
//!
//! The Serde ecosystem consists of data structures that know how to serialize
//! and deserialize themselves along with data formats that know how to
//! serialize and deserialize other things. Serde provides the layer by which
//! these two groups interact with each other, allowing any supported data
//! structure to be serialized and deserialized using any supported data format.
//!
//! See the Serde website [https://serde.rs/] for additional documentation and
//! usage examples.
//!
//! [https://serde.rs/]: https://serde.rs/
//!
//! ## Design
//!
//! Where many other languages rely on runtime reflection for serializing data,
//! Serde is instead built on Rust's powerful trait system. A data structure
//! that knows how to serialize and deserialize itself is one that implements
//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's derive
//! attribute to automatically generate implementations at compile time). This
//! avoids any overhead of reflection or runtime type information. In fact in
//! many situations the interaction between data structure and data format can
//! be completely optimized away by the Rust compiler, leaving Serde
//! serialization to perform the same speed as a handwritten serializer for the
//! specific selection of data structure and data format.
//!
//! ## Data formats
//!
//! The following is a partial list of data formats that have been implemented
//! for Serde by the community.
//!
//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
//! - [Bincode], a compact binary format
//!   used for IPC within the Servo rendering engine.
//! - [CBOR], a Concise Binary Object Representation designed for small message
//!   size without the need for version negotiation.
//! - [YAML], a popular human-friendly configuration language that ain't markup
//!   language.
//! - [MessagePack], an efficient binary format that resembles a compact JSON.
//! - [TOML], a minimal configuration format used by [Cargo].
//! - [Pickle], a format common in the Python world.
//! - [Hjson], a variant of JSON designed to be readable and writable by humans.
//! - [BSON], the data storage and network transfer format used by MongoDB.
//! - [URL], the x-www-form-urlencoded format.
//! - [XML], the flexible machine-friendly W3C standard.
//!   *(deserialization only)*
//! - [Envy], a way to deserialize environment variables into Rust structs.
//!   *(deserialization only)*
//! - [Redis], deserialize values from Redis when using [redis-rs].
//!   *(deserialization only)*
//!
//! [JSON]: https://github.com/serde-rs/json
//! [Bincode]: https://github.com/TyOverby/bincode
//! [CBOR]: https://github.com/pyfisch/cbor
//! [YAML]: https://github.com/dtolnay/serde-yaml
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
//! [TOML]: https://github.com/alexcrichton/toml-rs
//! [Pickle]: https://github.com/birkenfeld/serde-pickle
//! [Hjson]: https://github.com/laktak/hjson-rust
//! [BSON]: https://github.com/zonyitoo/bson-rs
//! [URL]: https://github.com/nox/serde_urlencoded
//! [XML]: https://github.com/RReverser/serde-xml-rs
//! [Envy]: https://github.com/softprops/envy
//! [Redis]: https://github.com/OneSignal/serde-redis
//! [Cargo]: http://doc.crates.io/manifest.html
//! [redis-rs]: https://crates.io/crates/redis

////////////////////////////////////////////////////////////////////////////////

// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.60")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
//    https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(specialization))]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
#![cfg_attr(
    feature = "cargo-clippy",
    allow(
        cast_lossless, const_static_lifetime, doc_markdown, linkedlist, needless_pass_by_value,
        redundant_field_names, type_complexity, unreadable_literal, zero_prefixed_literal
    )
)]
// Whitelisted clippy_pedantic lints
#![cfg_attr(feature = "cargo-clippy", allow(
// integer and float ser/de requires these sorts of casts
    cast_possible_truncation,
    cast_possible_wrap,
    cast_precision_loss,
    cast_sign_loss,
// simplifies some macros
    invalid_upcast_comparisons,
// things are often more readable this way
    decimal_literal_representation,
    option_unwrap_used,
    result_unwrap_used,
    shadow_reuse,
    single_match_else,
    stutter,
    use_self,
// not practical
    many_single_char_names,
    missing_docs_in_private_items,
    similar_names,
// alternative is not stable
    empty_enum,
    use_debug,
))]
// Blacklisted Rust lints.
#![deny(missing_docs, unused_imports)]

////////////////////////////////////////////////////////////////////////////////

#[cfg(feature = "alloc")]
extern crate alloc;

#[cfg(all(feature = "unstable", feature = "std"))]
extern crate core;

/// A facade around all the types we need from the `std`, `core`, and `alloc`
/// crates. This avoids elaborate import wrangling having to happen in every
/// module.
mod lib {
    mod core {
        #[cfg(not(feature = "std"))]
        pub use core::*;
        #[cfg(feature = "std")]
        pub use std::*;
    }

    pub use self::core::{cmp, iter, mem, num, ops, slice, str};
    pub use self::core::{f32, f64};
    pub use self::core::{i16, i32, i64, i8, isize};
    pub use self::core::{u16, u32, u64, u8, usize};

    pub use self::core::cell::{Cell, RefCell};
    pub use self::core::clone::{self, Clone};
    pub use self::core::convert::{self, From, Into};
    pub use self::core::default::{self, Default};
    pub use self::core::fmt::{self, Debug, Display};
    pub use self::core::marker::{self, PhantomData};
    pub use self::core::option::{self, Option};
    pub use self::core::result::{self, Result};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::borrow::{Cow, ToOwned};
    #[cfg(feature = "std")]
    pub use std::borrow::{Cow, ToOwned};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::string::{String, ToString};
    #[cfg(feature = "std")]
    pub use std::string::String;

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::vec::Vec;
    #[cfg(feature = "std")]
    pub use std::vec::Vec;

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::boxed::Box;
    #[cfg(feature = "std")]
    pub use std::boxed::Box;

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::rc::{Rc, Weak as RcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::rc::{Rc, Weak as RcWeak};

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::arc::{Arc, Weak as ArcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::sync::{Arc, Weak as ArcWeak};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
    #[cfg(feature = "std")]
    pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};

    #[cfg(feature = "std")]
    pub use std::{error, net};

    #[cfg(feature = "std")]
    pub use std::collections::{HashMap, HashSet};
    #[cfg(feature = "std")]
    pub use std::ffi::{CStr, CString, OsStr, OsString};
    #[cfg(feature = "std")]
    pub use std::hash::{BuildHasher, Hash};
    #[cfg(feature = "std")]
    pub use std::io::Write;
    #[cfg(feature = "std")]
    pub use std::num::Wrapping;
    #[cfg(feature = "std")]
    pub use std::path::{Path, PathBuf};
    #[cfg(feature = "std")]
    pub use std::sync::{Mutex, RwLock};
    #[cfg(feature = "std")]
    pub use std::time::{Duration, SystemTime, UNIX_EPOCH};
}

////////////////////////////////////////////////////////////////////////////////

#[macro_use]
mod macros;

#[macro_use]
mod integer128;

pub mod de;
pub mod ser;

#[doc(inline)]
pub use de::{Deserialize, Deserializer};
#[doc(inline)]
pub use ser::{Serialize, Serializer};

// Generated code uses these to support no_std. Not public API.
#[doc(hidden)]
pub mod export;

// Helpers used by generated code and doc tests. Not public API.
#[doc(hidden)]
pub mod private;

// Re-export #[derive(Serialize, Deserialize)].
//
// This is a workaround for https://github.com/rust-lang/cargo/issues/1286.
// Without this re-export, crates that put Serde derives behind a cfg_attr would
// need to use some silly feature name that depends on both serde and
// serde_derive.
//
//     [features]
//     serde-impls = ["serde", "serde_derive"]
//
//     [dependencies]
//     serde = { version = "1.0", optional = true }
//     serde_derive = { version = "1.0", optional = true }
//
//     # Used like this:
//     # #[cfg(feature = "serde-impls")]
//     # #[macro_use]
//     # extern crate serde_derive;
//     #
//     # #[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
//     # struct S { /* ... */ }
//
// The re-exported derives allow crates to use "serde" as the name of their
// Serde feature which is more intuitive.
//
//     [dependencies]
//     serde = { version = "1.0", optional = true, features = ["derive"] }
//
//     # Used like this:
//     # #[cfg(feature = "serde")]
//     # #[macro_use]
//     # extern crate serde;
//     #
//     # #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
//     # struct S { /* ... */ }
//
// The reason re-exporting is not enabled by default is that disabling it would
// be annoying for crates that provide handwritten impls or data formats. They
// would need to disable default features and then explicitly re-enable std.
#[cfg(feature = "serde_derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "serde_derive")]
#[doc(hidden)]
pub use serde_derive::*;
<commit_msg>Remove unneeded core import<commit_after>// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.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.

//! # Serde
//!
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
//! structures efficiently and generically.
//!
//! The Serde ecosystem consists of data structures that know how to serialize
//! and deserialize themselves along with data formats that know how to
//! serialize and deserialize other things. Serde provides the layer by which
//! these two groups interact with each other, allowing any supported data
//! structure to be serialized and deserialized using any supported data format.
//!
//! See the Serde website [https://serde.rs/] for additional documentation and
//! usage examples.
//!
//! [https://serde.rs/]: https://serde.rs/
//!
//! ## Design
//!
//! Where many other languages rely on runtime reflection for serializing data,
//! Serde is instead built on Rust's powerful trait system. A data structure
//! that knows how to serialize and deserialize itself is one that implements
//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's derive
//! attribute to automatically generate implementations at compile time). This
//! avoids any overhead of reflection or runtime type information. In fact in
//! many situations the interaction between data structure and data format can
//! be completely optimized away by the Rust compiler, leaving Serde
//! serialization to perform the same speed as a handwritten serializer for the
//! specific selection of data structure and data format.
//!
//! ## Data formats
//!
//! The following is a partial list of data formats that have been implemented
//! for Serde by the community.
//!
//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
//! - [Bincode], a compact binary format
//!   used for IPC within the Servo rendering engine.
//! - [CBOR], a Concise Binary Object Representation designed for small message
//!   size without the need for version negotiation.
//! - [YAML], a popular human-friendly configuration language that ain't markup
//!   language.
//! - [MessagePack], an efficient binary format that resembles a compact JSON.
//! - [TOML], a minimal configuration format used by [Cargo].
//! - [Pickle], a format common in the Python world.
//! - [Hjson], a variant of JSON designed to be readable and writable by humans.
//! - [BSON], the data storage and network transfer format used by MongoDB.
//! - [URL], the x-www-form-urlencoded format.
//! - [XML], the flexible machine-friendly W3C standard.
//!   *(deserialization only)*
//! - [Envy], a way to deserialize environment variables into Rust structs.
//!   *(deserialization only)*
//! - [Redis], deserialize values from Redis when using [redis-rs].
//!   *(deserialization only)*
//!
//! [JSON]: https://github.com/serde-rs/json
//! [Bincode]: https://github.com/TyOverby/bincode
//! [CBOR]: https://github.com/pyfisch/cbor
//! [YAML]: https://github.com/dtolnay/serde-yaml
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
//! [TOML]: https://github.com/alexcrichton/toml-rs
//! [Pickle]: https://github.com/birkenfeld/serde-pickle
//! [Hjson]: https://github.com/laktak/hjson-rust
//! [BSON]: https://github.com/zonyitoo/bson-rs
//! [URL]: https://github.com/nox/serde_urlencoded
//! [XML]: https://github.com/RReverser/serde-xml-rs
//! [Envy]: https://github.com/softprops/envy
//! [Redis]: https://github.com/OneSignal/serde-redis
//! [Cargo]: http://doc.crates.io/manifest.html
//! [redis-rs]: https://crates.io/crates/redis

////////////////////////////////////////////////////////////////////////////////

// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.60")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
//    https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(specialization))]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
#![cfg_attr(
    feature = "cargo-clippy",
    allow(
        cast_lossless, const_static_lifetime, doc_markdown, linkedlist, needless_pass_by_value,
        redundant_field_names, type_complexity, unreadable_literal, zero_prefixed_literal
    )
)]
// Whitelisted clippy_pedantic lints
#![cfg_attr(feature = "cargo-clippy", allow(
// integer and float ser/de requires these sorts of casts
    cast_possible_truncation,
    cast_possible_wrap,
    cast_precision_loss,
    cast_sign_loss,
// simplifies some macros
    invalid_upcast_comparisons,
// things are often more readable this way
    decimal_literal_representation,
    option_unwrap_used,
    result_unwrap_used,
    shadow_reuse,
    single_match_else,
    stutter,
    use_self,
// not practical
    many_single_char_names,
    missing_docs_in_private_items,
    similar_names,
// alternative is not stable
    empty_enum,
    use_debug,
))]
// Blacklisted Rust lints.
#![deny(missing_docs, unused_imports)]

////////////////////////////////////////////////////////////////////////////////

#[cfg(feature = "alloc")]
extern crate alloc;

/// A facade around all the types we need from the `std`, `core`, and `alloc`
/// crates. This avoids elaborate import wrangling having to happen in every
/// module.
mod lib {
    mod core {
        #[cfg(not(feature = "std"))]
        pub use core::*;
        #[cfg(feature = "std")]
        pub use std::*;
    }

    pub use self::core::{cmp, iter, mem, num, ops, slice, str};
    pub use self::core::{f32, f64};
    pub use self::core::{i16, i32, i64, i8, isize};
    pub use self::core::{u16, u32, u64, u8, usize};

    pub use self::core::cell::{Cell, RefCell};
    pub use self::core::clone::{self, Clone};
    pub use self::core::convert::{self, From, Into};
    pub use self::core::default::{self, Default};
    pub use self::core::fmt::{self, Debug, Display};
    pub use self::core::marker::{self, PhantomData};
    pub use self::core::option::{self, Option};
    pub use self::core::result::{self, Result};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::borrow::{Cow, ToOwned};
    #[cfg(feature = "std")]
    pub use std::borrow::{Cow, ToOwned};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::string::{String, ToString};
    #[cfg(feature = "std")]
    pub use std::string::String;

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::vec::Vec;
    #[cfg(feature = "std")]
    pub use std::vec::Vec;

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::boxed::Box;
    #[cfg(feature = "std")]
    pub use std::boxed::Box;

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::rc::{Rc, Weak as RcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::rc::{Rc, Weak as RcWeak};

    #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
    pub use alloc::arc::{Arc, Weak as ArcWeak};
    #[cfg(all(feature = "rc", feature = "std"))]
    pub use std::sync::{Arc, Weak as ArcWeak};

    #[cfg(all(feature = "alloc", not(feature = "std")))]
    pub use alloc::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
    #[cfg(feature = "std")]
    pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};

    #[cfg(feature = "std")]
    pub use std::{error, net};

    #[cfg(feature = "std")]
    pub use std::collections::{HashMap, HashSet};
    #[cfg(feature = "std")]
    pub use std::ffi::{CStr, CString, OsStr, OsString};
    #[cfg(feature = "std")]
    pub use std::hash::{BuildHasher, Hash};
    #[cfg(feature = "std")]
    pub use std::io::Write;
    #[cfg(feature = "std")]
    pub use std::num::Wrapping;
    #[cfg(feature = "std")]
    pub use std::path::{Path, PathBuf};
    #[cfg(feature = "std")]
    pub use std::sync::{Mutex, RwLock};
    #[cfg(feature = "std")]
    pub use std::time::{Duration, SystemTime, UNIX_EPOCH};
}

////////////////////////////////////////////////////////////////////////////////

#[macro_use]
mod macros;

#[macro_use]
mod integer128;

pub mod de;
pub mod ser;

#[doc(inline)]
pub use de::{Deserialize, Deserializer};
#[doc(inline)]
pub use ser::{Serialize, Serializer};

// Generated code uses these to support no_std. Not public API.
#[doc(hidden)]
pub mod export;

// Helpers used by generated code and doc tests. Not public API.
#[doc(hidden)]
pub mod private;

// Re-export #[derive(Serialize, Deserialize)].
//
// This is a workaround for https://github.com/rust-lang/cargo/issues/1286.
// Without this re-export, crates that put Serde derives behind a cfg_attr would
// need to use some silly feature name that depends on both serde and
// serde_derive.
//
//     [features]
//     serde-impls = ["serde", "serde_derive"]
//
//     [dependencies]
//     serde = { version = "1.0", optional = true }
//     serde_derive = { version = "1.0", optional = true }
//
//     # Used like this:
//     # #[cfg(feature = "serde-impls")]
//     # #[macro_use]
//     # extern crate serde_derive;
//     #
//     # #[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
//     # struct S { /* ... */ }
//
// The re-exported derives allow crates to use "serde" as the name of their
// Serde feature which is more intuitive.
//
//     [dependencies]
//     serde = { version = "1.0", optional = true, features = ["derive"] }
//
//     # Used like this:
//     # #[cfg(feature = "serde")]
//     # #[macro_use]
//     # extern crate serde;
//     #
//     # #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
//     # struct S { /* ... */ }
//
// The reason re-exporting is not enabled by default is that disabling it would
// be annoying for crates that provide handwritten impls or data formats. They
// would need to disable default features and then explicitly re-enable std.
#[cfg(feature = "serde_derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "serde_derive")]
#[doc(hidden)]
pub use serde_derive::*;
<|endoftext|>


<commit_before>/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

use lsp_server::{
    ErrorCode, Request as ServerRequest, RequestId, RequestId as ServerRequestId,
    Response as ServerResponse, ResponseError,
};
use lsp_types::request::Request;

use crate::lsp_runtime_error::{LSPRuntimeError, LSPRuntimeResult};

pub struct LSPRequestDispatch<'state, TState> {
    request: lsp_server::Request,
    state: &'state TState,
}

impl<'state, TState> LSPRequestDispatch<'state, TState> {
    pub fn new(request: lsp_server::Request, state: &'state TState) -> Self {
        LSPRequestDispatch { request, state }
    }

    /// Calls handler if the LSPRequestDispatch's request's method matches the method
    /// of TRequest. Returns a Result which will be Ok if the handler was not called,
    /// or Err if the handler was called.
    /// Thus, multiple calls to `on_request_sync(...)?` can be chained. Doing so will
    /// cause LSPRequestDispatch to execute the first matching handler, if any.
    pub fn on_request_sync<TRequest: Request>(
        self,
        handler: fn(&TState, TRequest::Params) -> LSPRuntimeResult<TRequest::Result>,
    ) -> Result<Self, ServerResponse> {
        if self.request.method == TRequest::METHOD {
            match extract_request_params::<TRequest>(self.request) {
                Ok((request_id, params)) => {
                    let response = handler(self.state, params).and_then(|handler_result| {
                        serde_json::to_value(handler_result).map_err(|_err| {
                            LSPRuntimeError::UnexpectedError(
                                "Unable to serialize request response".to_string(),
                            )
                        })
                    });
                    let server_response = convert_to_lsp_response(request_id, response);

                    return Err(server_response);
                }
                Err(error) => {
                    return Err(convert_to_lsp_response(
                        ServerRequestId::from("default-lsp-id".to_string()),
                        Err(error),
                    ));
                }
            }
        }

        Ok(self)
    }

    pub fn request(self) -> lsp_server::Request {
        self.request
    }
}

fn convert_to_lsp_response(
    id: RequestId,
    result: LSPRuntimeResult<serde_json::Value>,
) -> ServerResponse {
    match result {
        Ok(result) => ServerResponse {
            id,
            result: Some(result),
            error: None,
        },
        Err(runtime_error) => {
            let response_error: Option<ResponseError> = runtime_error.into();
            let response_error = response_error.unwrap_or_else(|| ResponseError {
                code: ErrorCode::RequestCanceled as i32,
                message: "Request Canceled".to_string(),
                data: None,
            });
            ServerResponse {
                id,
                result: None,
                error: Some(response_error),
            }
        }
    }
}

fn extract_request_params<R>(req: ServerRequest) -> LSPRuntimeResult<(ServerRequestId, R::Params)>
where
    R: Request,
{
    std::panic::catch_unwind(|| {
        req.extract(R::METHOD)
            .expect("extract_request_params: could not extract request params")
    })
    .map_err(|err| {
        LSPRuntimeError::UnexpectedError(format!(
            "panic in the `extract_request_params`: {:?}",
            err
        ))
    })
}

#[cfg(test)]
mod test {
    use crate::lsp_runtime_error::LSPRuntimeResult;
    use lsp_types::{
        request::Request,
        request::{GotoDefinition, HoverRequest},
        Position, TextDocumentIdentifier, TextDocumentPositionParams, Url,
    };
    use std::sync::atomic::{AtomicI32, Ordering};

    use super::LSPRequestDispatch;

    #[test]
    fn calls_first_matching_request_handler() {
        let state: AtomicI32 = AtomicI32::new(0);
        let dispatch = LSPRequestDispatch::new(
            lsp_server::Request {
                id: "id".to_string().into(),
                method: "textDocument/definition".to_string(),
                params: serde_json::to_value(TextDocumentPositionParams {
                    text_document: TextDocumentIdentifier {
                        uri: Url::parse("https://example.net").unwrap(),
                    },
                    position: Position {
                        line: 0,
                        character: 0,
                    },
                })
                .unwrap(),
            },
            &state,
        );
        let dispatch = || -> Result<(), super::ServerResponse> {
            dispatch
                .on_request_sync::<HoverRequest>(hover_handler)?
                .on_request_sync::<GotoDefinition>(goto_definition_handler)?;
            Ok(())
        };
        let result = dispatch();
        assert!(result.is_err());
        assert_eq!(state.load(Ordering::Relaxed), 2);
    }

    fn hover_handler(
        state: &AtomicI32,
        _params: <HoverRequest as Request>::Params,
    ) -> LSPRuntimeResult<<HoverRequest as Request>::Result> {
        state.store(1, Ordering::Relaxed);

        Ok(None)
    }

    fn goto_definition_handler(
        state: &AtomicI32,
        _params: <GotoDefinition as Request>::Params,
    ) -> LSPRuntimeResult<<GotoDefinition as Request>::Result> {
        state.store(2, Ordering::Relaxed);

        Ok(None)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use lsp_types::request::CodeActionRequest;
    use serde_json::json;

    #[test]
    fn test_extract_request_params_error() {
        let request_id = ServerRequestId::from("test-id".to_string());
        let request = ServerRequest {
            id: request_id,
            method: "textDocument/codeAction".to_string(),
            params: json!({
                "invalid_key": "invalid_value",
            }),
        };
        let result = extract_request_params::<CodeActionRequest>(request);
        // it returns an error, but not panic
        assert!(result.is_err());
    }
}
<commit_msg>Change default response error code to avoid blocking codeactions<commit_after>/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

use lsp_server::{
    ErrorCode, Request as ServerRequest, RequestId, RequestId as ServerRequestId,
    Response as ServerResponse, ResponseError,
};
use lsp_types::request::Request;

use crate::lsp_runtime_error::{LSPRuntimeError, LSPRuntimeResult};

pub struct LSPRequestDispatch<'state, TState> {
    request: lsp_server::Request,
    state: &'state TState,
}

impl<'state, TState> LSPRequestDispatch<'state, TState> {
    pub fn new(request: lsp_server::Request, state: &'state TState) -> Self {
        LSPRequestDispatch { request, state }
    }

    /// Calls handler if the LSPRequestDispatch's request's method matches the method
    /// of TRequest. Returns a Result which will be Ok if the handler was not called,
    /// or Err if the handler was called.
    /// Thus, multiple calls to `on_request_sync(...)?` can be chained. Doing so will
    /// cause LSPRequestDispatch to execute the first matching handler, if any.
    pub fn on_request_sync<TRequest: Request>(
        self,
        handler: fn(&TState, TRequest::Params) -> LSPRuntimeResult<TRequest::Result>,
    ) -> Result<Self, ServerResponse> {
        if self.request.method == TRequest::METHOD {
            match extract_request_params::<TRequest>(self.request) {
                Ok((request_id, params)) => {
                    let response = handler(self.state, params).and_then(|handler_result| {
                        serde_json::to_value(handler_result).map_err(|_err| {
                            LSPRuntimeError::UnexpectedError(
                                "Unable to serialize request response".to_string(),
                            )
                        })
                    });
                    let server_response = convert_to_lsp_response(request_id, response);

                    return Err(server_response);
                }
                Err(error) => {
                    return Err(convert_to_lsp_response(
                        ServerRequestId::from("default-lsp-id".to_string()),
                        Err(error),
                    ));
                }
            }
        }

        Ok(self)
    }

    pub fn request(self) -> lsp_server::Request {
        self.request
    }
}

fn convert_to_lsp_response(
    id: RequestId,
    result: LSPRuntimeResult<serde_json::Value>,
) -> ServerResponse {
    match result {
        Ok(result) => ServerResponse {
            id,
            result: Some(result),
            error: None,
        },
        Err(runtime_error) => {
            let response_error: Option<ResponseError> = runtime_error.into();
            let response_error = response_error.unwrap_or_else(|| ResponseError {
                code: ErrorCode::UnknownErrorCode as i32,
                message: "Request Canceled".to_string(),
                data: None,
            });
            ServerResponse {
                id,
                result: None,
                error: Some(response_error),
            }
        }
    }
}

fn extract_request_params<R>(req: ServerRequest) -> LSPRuntimeResult<(ServerRequestId, R::Params)>
where
    R: Request,
{
    std::panic::catch_unwind(|| {
        req.extract(R::METHOD)
            .expect("extract_request_params: could not extract request params")
    })
    .map_err(|err| {
        LSPRuntimeError::UnexpectedError(format!(
            "panic in the `extract_request_params`: {:?}",
            err
        ))
    })
}

#[cfg(test)]
mod test {
    use crate::lsp_runtime_error::LSPRuntimeResult;
    use lsp_types::{
        request::Request,
        request::{GotoDefinition, HoverRequest},
        Position, TextDocumentIdentifier, TextDocumentPositionParams, Url,
    };
    use std::sync::atomic::{AtomicI32, Ordering};

    use super::LSPRequestDispatch;

    #[test]
    fn calls_first_matching_request_handler() {
        let state: AtomicI32 = AtomicI32::new(0);
        let dispatch = LSPRequestDispatch::new(
            lsp_server::Request {
                id: "id".to_string().into(),
                method: "textDocument/definition".to_string(),
                params: serde_json::to_value(TextDocumentPositionParams {
                    text_document: TextDocumentIdentifier {
                        uri: Url::parse("https://example.net").unwrap(),
                    },
                    position: Position {
                        line: 0,
                        character: 0,
                    },
                })
                .unwrap(),
            },
            &state,
        );
        let dispatch = || -> Result<(), super::ServerResponse> {
            dispatch
                .on_request_sync::<HoverRequest>(hover_handler)?
                .on_request_sync::<GotoDefinition>(goto_definition_handler)?;
            Ok(())
        };
        let result = dispatch();
        assert!(result.is_err());
        assert_eq!(state.load(Ordering::Relaxed), 2);
    }

    fn hover_handler(
        state: &AtomicI32,
        _params: <HoverRequest as Request>::Params,
    ) -> LSPRuntimeResult<<HoverRequest as Request>::Result> {
        state.store(1, Ordering::Relaxed);

        Ok(None)
    }

    fn goto_definition_handler(
        state: &AtomicI32,
        _params: <GotoDefinition as Request>::Params,
    ) -> LSPRuntimeResult<<GotoDefinition as Request>::Result> {
        state.store(2, Ordering::Relaxed);

        Ok(None)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use lsp_types::request::CodeActionRequest;
    use serde_json::json;

    #[test]
    fn test_extract_request_params_error() {
        let request_id = ServerRequestId::from("test-id".to_string());
        let request = ServerRequest {
            id: request_id,
            method: "textDocument/codeAction".to_string(),
            params: json!({
                "invalid_key": "invalid_value",
            }),
        };
        let result = extract_request_params::<CodeActionRequest>(request);
        // it returns an error, but not panic
        assert!(result.is_err());
    }
}
<|endoftext|>