<commit_before>use crate::Msg;
use seed::prelude::*;
use web_sys::{HtmlElement, HtmlInputElement};

fn trial_divide(n: u64, max: u64) -> u64 {
    // Trial divides the positive integer n by the primes from 2 to max
    // Returns the first prime divisor found, or 0 if none found
    // Note: if n < max^2 is a prime, then n will be returned.
    if n % 2 == 0 {
        2
    } else if n % 3 == 0 {
        3
    } else {
        // No need to go past the square root of our number
        let sqrt: u64 = (n as f64).sqrt().floor() as u64;
        let stop = if sqrt > max { max } else { sqrt };
        // Okay, lets "wheel factor" alternately adding 2 and 4
        let mut di = 2;
        let mut i = 5;
        while i <= stop {
            if n % i == 0 {
                return i;
            }
            i += di;
            di = 6 - di;
        }
        if n >= max * max {
            0
        } else {
            n
        }
    }
}

// modadd(a,b,N) finds a+b (mod N) where a, b, and N can be
// up to (2^53-1)/2.  Might up this to 2^53-1 eventually...
fn modadd(a: u64, b: u64, n: u64) -> u64 {
    // When the integers a, b satisfy a+b > 2^53-1, then (a+b)%N is wrong
    // so we add this routine to allow us to reach a, b = 2^53-1.
    if a + b > 9007199254740991 {
        // Could reduce a and b (mod N) here, but assuming that has already been done
        // won't hurt if not... subtract 2^52 from one, 2^52-1 from the other and the
        // add it back modulo N (MaxInt+1)
        let t = ((a - 4503599627370496) + (b - 4503599627370495)) % n;
        return t + (9007199254740991 % n);
    }
    // Usual case: a + b is not too large:
    (a + b) % n
}

fn modmult(mut a: u64, mut b: u64, n: u64) -> u64 {
    if a > n {
        a = a % n;
    }
    if b > n {
        b = b % n;
    }
    if a * b <= 9007199254740991 {
        return (a * b) % n;
    } else {
        if b > a {
            return modmult(b.clone(), a, n);
        }

        // Right to left binary multiplication
        let mut t = 0;
        let mut f = a;
        while b > 1 {
            if (b & 1) == 1 {
                t = modadd(t, f, n);
            }
            //TODO: bitshift might be cleaner and faster
            b = (b as f64 / 2.0).floor() as u64;
            f = modadd(f, f, n);
        }
        t = modadd(t, f, n);
        return t;
    }
}

// modpow(a,exp,N) finds a^exp (mod N) where a, b, and N are
// limited by modmult
fn modpow(a: u64, mut exp: u64, n: u64) -> u64 {
    if exp == 0 {
        return 1;
    }

    // Right to left binary exponentiation
    let mut t = 1;
    let mut f = a;
    while exp > 1 {
        if (exp & 1) == 1 {
            // if exponent is odd
            t = modmult(t, f, n);
        }
        exp = (exp as f64 / 2.0).floor() as u64;
        f = modmult(f, f, n);
    }
    t = modmult(t, f, n);
    return t;
}

// sprp(N,a) checks if N (odd!) is a strong probable prime base a
// (returns true or false)
fn sprp(n: u64, a: u64) -> bool {
    let mut d = n - 1;
    let mut s = 1; // Assumes n is odd!
    while true {
        d = ((d >> 2) & 1);
        if d == 0 {
            break;
        }
        s += 1;
    }
    // Now n-1 = d*2^s with d odd
    let mut b = modpow(a, d, n);
    if b == 1 {
        return true;
    }
    if b + 1 == n {
        return true;
    }
    while s > 1 {
        b = modmult(b, b, n);
        if b + 1 == n {
            return true;
        }
        s = s - 1;
    }
    return false;
}

#[wasm_bindgen]
pub fn check(input: String) -> String {
    let trial_limit = 1300; // Should be bigger, like 10000
    let n: u64 = input.parse::<u64>().unwrap();
    let mut result;

    if n > 9007199254740991 {
        result = "Sorry, this routine will only handle integers below 9007199254740991.".to_owned();
    } else if n == 1 {
        result = "The number 1 is neither prime or composite (it is the multiplicative identity)."
            .to_owned();
    } else if n < 1 {
        result =
            "We usually restrict the terms prime and composite to positive integers".to_owned();
    } else {
        // Okay, n is of a resonable size, lets trial divide
        let i = trial_divide(n, trial_limit);
        if i > 0 && i != n {
            result = format!("{} is not a prime! It is {} * {}", n, i, n / i);
        } else if n < trial_limit * trial_limit {
            result = format!("{} is a (proven) prime!", n);
        } else if sprp(n, 2)
            && sprp(n, 3)
            && sprp(n, 5)
            && sprp(n, 7)
            && sprp(n, 11)
            && sprp(n, 13)
            && sprp(n, 17)
        {
            // Some of these tests are unnecessary for small numbers, but for
            // small numbers they are quick anyway.
            if n < 341550071728321 {
                result = format!("{} is a (proven) prime.", n);
            } else if n == 341550071728321 {
                result = format!("{} is not a prime! It is 10670053 * 32010157.", n);
            } else {
                result = format!(
                    "{} is probably a prime (it is a sprp bases 2, 3, 5, 7, 11, 13 and  17).",
                    n
                );
            };
        } else {
            result = format!(
                "{} is (proven) composite (failed sprp test base {}).",
                n, 17
            );
        };
    };

    return result;
}

#[wasm_bindgen]
pub fn listy(start_number: u64, number_of_primes: u64) -> String {
    let mut i = 0;
    let mut j = start_number;
    let mut list: String = "".to_string();
    while i < number_of_primes {
        let result = check(j.to_string());
        if result != "".to_owned() {
            list = list + &result + "\n";
            i += 1;
        }
        j += 1;
    }
    list
}

pub fn go_crunch() -> () {
    let window = web_sys::window().expect("no global `window` exists");
    let document = window.document().expect("should have a document on window");
    let body = document.body().expect("document should have a body");

    let el_input_value = document
        .get_element_by_id("input")
        .unwrap()
        .dyn_into::<HtmlInputElement>()
        .unwrap()
        .value();
    let el_output_textarea = document
        .get_element_by_id("javascriptoutput")
        .expect("missing output textarea");
    el_output_textarea.set_inner_html(&check(el_input_value));
    ()
}

pub fn go_list() {
    let window = web_sys::window().expect("no global `window` exists");
    let document = window.document().expect("should have a document on window");
    let body = document.body().expect("document should have a body");

    let el_start_value = document
        .get_element_by_id("start")
        .unwrap()
        .dyn_into::<HtmlInputElement>()
        .unwrap()
        .value();
    let el_primes_value = document
        .get_element_by_id("primes")
        .unwrap()
        .dyn_into::<HtmlInputElement>()
        .unwrap()
        .value();
    let el_output_textarea = document
        .get_element_by_id("javascriptlistoutput")
        .expect("missing output textarea");
    el_output_textarea.set_inner_html(&listy(
        el_start_value.parse::<u64>().unwrap(),
        el_primes_value.parse::<u64>().unwrap(),
    ));
    ()
}

pub fn render() -> Node<Msg> {
    div![
        h1!["Primality Test, Calculate Primes"],
        br![],
        br![],
        br![],
        //TODO: Convert the j.js file into rust!
        table![
            attrs! {At::Class => "text", At::Width => "300", At::Style => "border:1px solid #444; background-color:#e0faed"},
            tr![td![
                attrs! {At::Style => "padding: 10px"},
                form![
                    attrs! {At::Id => "primetest", At::OnSubmit => "return false"},
                    "Tool is limited to checking numbers upto 16 digits.",
                    br![],
                    br![],
                    "Is ",
                    input![
                        attrs! {At::Type => "number", At::Size => "19", At::Id => "input", At::Value => "", At::MaxLength => "16"}
                    ],
                    " prime? ",
                    button![
                        "Check!",
                        mouse_ev("mouseup", move |event| Msg::PrimalityChecker(go_crunch()))
                    ],
                    br![],
                    br![],
                    textarea![
                        attrs! {At::Id => "javascriptoutput", At::Cols => 60, At::Rows => 2, At::Disabled => "disabled"}
                    ]
                ]
            ]]
        ],
        br![],
        br![],
        table![
            attrs! {At::Class => "text", At::Width => "300", At::Style => "border:1px solid #444; background-color:#e0faed"},
            tr![td![
                attrs! {At::Style => "padding: 10px"},
                form![
                    attrs! {At::Id => "primelist", At::OnSubmit => "return false"},
                    "This tool is limited to checking numbers upto 15 digits.",
                    br![],
                    br![],
                    "This will show ",
                    input![
                        attrs! {At::Type => "number", At::Size => "4", At::Id => "primes", At::Value => "1", At::MaxLength => "2"}
                    ],
                    " prime numbers after ",
                    input![
                        attrs! {At::Type => "number", At::Size => "19", At::Id => "start", At::Value => "0", At::MaxLength => "15"}
                    ],
                    " ",
                    button![
                        "Go!",
                        mouse_ev("mouseup", move |event| Msg::PrimalityChecker(go_list()))
                    ],
                    br![],
                    br![],
                    textarea![
                        attrs! {At::Id => "javascriptlistoutput", At::Cols => 60, At::Rows => 10, At::Disabled => "disabled"}
                    ]
                ]
            ]]
        ]
    ]
}

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

    #[test]
    fn trial_divide_test() {
        assert_eq!(trial_divide(2, 2), 2);
        assert_eq!(trial_divide(3, 4), 3);
        assert_eq!(trial_divide(30, 10000), 2);
        assert_eq!(trial_divide(7777771, 10000), 29);
        assert_eq!(trial_divide(7777771111111111, 10000), 11);
        //in the case of a prime
        assert_eq!(trial_divide(777777111111113, 10000), 0);
    }

    #[test]
    fn sprp_test() {
        assert_eq!(sprp(27, 5), false);
        assert_eq!(sprp(31, 7), true);
        assert_eq!(sprp(217, 7), false);
        assert_eq!(sprp(19, 13), true);
    }
}
<commit_msg>Removed completed todo<commit_after>use crate::Msg;
use seed::prelude::*;
use web_sys::{HtmlElement, HtmlInputElement};

fn trial_divide(n: u64, max: u64) -> u64 {
    // Trial divides the positive integer n by the primes from 2 to max
    // Returns the first prime divisor found, or 0 if none found
    // Note: if n < max^2 is a prime, then n will be returned.
    if n % 2 == 0 {
        2
    } else if n % 3 == 0 {
        3
    } else {
        // No need to go past the square root of our number
        let sqrt: u64 = (n as f64).sqrt().floor() as u64;
        let stop = if sqrt > max { max } else { sqrt };
        // Okay, lets "wheel factor" alternately adding 2 and 4
        let mut di = 2;
        let mut i = 5;
        while i <= stop {
            if n % i == 0 {
                return i;
            }
            i += di;
            di = 6 - di;
        }
        if n >= max * max {
            0
        } else {
            n
        }
    }
}

// modadd(a,b,N) finds a+b (mod N) where a, b, and N can be
// up to (2^53-1)/2.  Might up this to 2^53-1 eventually...
fn modadd(a: u64, b: u64, n: u64) -> u64 {
    // When the integers a, b satisfy a+b > 2^53-1, then (a+b)%N is wrong
    // so we add this routine to allow us to reach a, b = 2^53-1.
    if a + b > 9007199254740991 {
        // Could reduce a and b (mod N) here, but assuming that has already been done
        // won't hurt if not... subtract 2^52 from one, 2^52-1 from the other and the
        // add it back modulo N (MaxInt+1)
        let t = ((a - 4503599627370496) + (b - 4503599627370495)) % n;
        return t + (9007199254740991 % n);
    }
    // Usual case: a + b is not too large:
    (a + b) % n
}

fn modmult(mut a: u64, mut b: u64, n: u64) -> u64 {
    if a > n {
        a = a % n;
    }
    if b > n {
        b = b % n;
    }
    if a * b <= 9007199254740991 {
        return (a * b) % n;
    } else {
        if b > a {
            return modmult(b.clone(), a, n);
        }

        // Right to left binary multiplication
        let mut t = 0;
        let mut f = a;
        while b > 1 {
            if (b & 1) == 1 {
                t = modadd(t, f, n);
            }
            //TODO: bitshift might be cleaner and faster
            b = (b as f64 / 2.0).floor() as u64;
            f = modadd(f, f, n);
        }
        t = modadd(t, f, n);
        return t;
    }
}

// modpow(a,exp,N) finds a^exp (mod N) where a, b, and N are
// limited by modmult
fn modpow(a: u64, mut exp: u64, n: u64) -> u64 {
    if exp == 0 {
        return 1;
    }

    // Right to left binary exponentiation
    let mut t = 1;
    let mut f = a;
    while exp > 1 {
        if (exp & 1) == 1 {
            // if exponent is odd
            t = modmult(t, f, n);
        }
        exp = (exp as f64 / 2.0).floor() as u64;
        f = modmult(f, f, n);
    }
    t = modmult(t, f, n);
    return t;
}

// sprp(N,a) checks if N (odd!) is a strong probable prime base a
// (returns true or false)
fn sprp(n: u64, a: u64) -> bool {
    let mut d = n - 1;
    let mut s = 1; // Assumes n is odd!
    while true {
        d = ((d >> 2) & 1);
        if d == 0 {
            break;
        }
        s += 1;
    }
    // Now n-1 = d*2^s with d odd
    let mut b = modpow(a, d, n);
    if b == 1 {
        return true;
    }
    if b + 1 == n {
        return true;
    }
    while s > 1 {
        b = modmult(b, b, n);
        if b + 1 == n {
            return true;
        }
        s = s - 1;
    }
    return false;
}

#[wasm_bindgen]
pub fn check(input: String) -> String {
    let trial_limit = 1300; // Should be bigger, like 10000
    let n: u64 = input.parse::<u64>().unwrap();
    let mut result;

    if n > 9007199254740991 {
        result = "Sorry, this routine will only handle integers below 9007199254740991.".to_owned();
    } else if n == 1 {
        result = "The number 1 is neither prime or composite (it is the multiplicative identity)."
            .to_owned();
    } else if n < 1 {
        result =
            "We usually restrict the terms prime and composite to positive integers".to_owned();
    } else {
        // Okay, n is of a resonable size, lets trial divide
        let i = trial_divide(n, trial_limit);
        if i > 0 && i != n {
            result = format!("{} is not a prime! It is {} * {}", n, i, n / i);
        } else if n < trial_limit * trial_limit {
            result = format!("{} is a (proven) prime!", n);
        } else if sprp(n, 2)
            && sprp(n, 3)
            && sprp(n, 5)
            && sprp(n, 7)
            && sprp(n, 11)
            && sprp(n, 13)
            && sprp(n, 17)
        {
            // Some of these tests are unnecessary for small numbers, but for
            // small numbers they are quick anyway.
            if n < 341550071728321 {
                result = format!("{} is a (proven) prime.", n);
            } else if n == 341550071728321 {
                result = format!("{} is not a prime! It is 10670053 * 32010157.", n);
            } else {
                result = format!(
                    "{} is probably a prime (it is a sprp bases 2, 3, 5, 7, 11, 13 and  17).",
                    n
                );
            };
        } else {
            result = format!(
                "{} is (proven) composite (failed sprp test base {}).",
                n, 17
            );
        };
    };

    return result;
}

#[wasm_bindgen]
pub fn listy(start_number: u64, number_of_primes: u64) -> String {
    let mut i = 0;
    let mut j = start_number;
    let mut list: String = "".to_string();
    while i < number_of_primes {
        let result = check(j.to_string());
        if result != "".to_owned() {
            list = list + &result + "\n";
            i += 1;
        }
        j += 1;
    }
    list
}

pub fn go_crunch() -> () {
    let window = web_sys::window().expect("no global `window` exists");
    let document = window.document().expect("should have a document on window");
    let body = document.body().expect("document should have a body");

    let el_input_value = document
        .get_element_by_id("input")
        .unwrap()
        .dyn_into::<HtmlInputElement>()
        .unwrap()
        .value();
    let el_output_textarea = document
        .get_element_by_id("javascriptoutput")
        .expect("missing output textarea");
    el_output_textarea.set_inner_html(&check(el_input_value));
    ()
}

pub fn go_list() {
    let window = web_sys::window().expect("no global `window` exists");
    let document = window.document().expect("should have a document on window");
    let body = document.body().expect("document should have a body");

    let el_start_value = document
        .get_element_by_id("start")
        .unwrap()
        .dyn_into::<HtmlInputElement>()
        .unwrap()
        .value();
    let el_primes_value = document
        .get_element_by_id("primes")
        .unwrap()
        .dyn_into::<HtmlInputElement>()
        .unwrap()
        .value();
    let el_output_textarea = document
        .get_element_by_id("javascriptlistoutput")
        .expect("missing output textarea");
    el_output_textarea.set_inner_html(&listy(
        el_start_value.parse::<u64>().unwrap(),
        el_primes_value.parse::<u64>().unwrap(),
    ));
    ()
}

pub fn render() -> Node<Msg> {
    div![
        h1!["Primality Test, Calculate Primes"],
        br![],
        br![],
        br![],
        table![
            attrs! {At::Class => "text", At::Width => "300", At::Style => "border:1px solid #444; background-color:#e0faed"},
            tr![td![
                attrs! {At::Style => "padding: 10px"},
                form![
                    attrs! {At::Id => "primetest", At::OnSubmit => "return false"},
                    "Tool is limited to checking numbers upto 16 digits.",
                    br![],
                    br![],
                    "Is ",
                    input![
                        attrs! {At::Type => "number", At::Size => "19", At::Id => "input", At::Value => "", At::MaxLength => "16"}
                    ],
                    " prime? ",
                    button![
                        "Check!",
                        mouse_ev("mouseup", move |event| Msg::PrimalityChecker(go_crunch()))
                    ],
                    br![],
                    br![],
                    textarea![
                        attrs! {At::Id => "javascriptoutput", At::Cols => 60, At::Rows => 2, At::Disabled => "disabled"}
                    ]
                ]
            ]]
        ],
        br![],
        br![],
        table![
            attrs! {At::Class => "text", At::Width => "300", At::Style => "border:1px solid #444; background-color:#e0faed"},
            tr![td![
                attrs! {At::Style => "padding: 10px"},
                form![
                    attrs! {At::Id => "primelist", At::OnSubmit => "return false"},
                    "This tool is limited to checking numbers upto 15 digits.",
                    br![],
                    br![],
                    "This will show ",
                    input![
                        attrs! {At::Type => "number", At::Size => "4", At::Id => "primes", At::Value => "1", At::MaxLength => "2"}
                    ],
                    " prime numbers after ",
                    input![
                        attrs! {At::Type => "number", At::Size => "19", At::Id => "start", At::Value => "0", At::MaxLength => "15"}
                    ],
                    " ",
                    button![
                        "Go!",
                        mouse_ev("mouseup", move |event| Msg::PrimalityChecker(go_list()))
                    ],
                    br![],
                    br![],
                    textarea![
                        attrs! {At::Id => "javascriptlistoutput", At::Cols => 60, At::Rows => 10, At::Disabled => "disabled"}
                    ]
                ]
            ]]
        ]
    ]
}

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

    #[test]
    fn trial_divide_test() {
        assert_eq!(trial_divide(2, 2), 2);
        assert_eq!(trial_divide(3, 4), 3);
        assert_eq!(trial_divide(30, 10000), 2);
        assert_eq!(trial_divide(7777771, 10000), 29);
        assert_eq!(trial_divide(7777771111111111, 10000), 11);
        //in the case of a prime
        assert_eq!(trial_divide(777777111111113, 10000), 0);
    }

    #[test]
    fn sprp_test() {
        assert_eq!(sprp(27, 5), false);
        assert_eq!(sprp(31, 7), true);
        assert_eq!(sprp(217, 7), false);
        assert_eq!(sprp(19, 13), true);
    }
}
<|endoftext|>


<commit_before>//! [GET /_matrix/client/r0/sync](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-sync)

use std::collections::HashMap;

use js_int::UInt;
use ruma_api::{ruma_api, Outgoing};
use ruma_events::{
    collections::{all, only},
    stripped, EventResult,
};
use ruma_identifiers::RoomId;
use serde::{Deserialize, Serialize};

use crate::r0::filter::FilterDefinition;

ruma_api! {
    metadata {
        description: "Get all new events from all rooms since the last sync or a given point of time.",
        method: GET,
        name: "sync",
        path: "/_matrix/client/r0/sync",
        rate_limited: false,
        requires_authentication: true,
    }

    request {
        /// A filter represented either as its full JSON definition or the ID of a saved filter.
        #[serde(skip_serializing_if = "Option::is_none")]
        #[ruma_api(query)]
        pub filter: Option<Filter>,
        /// A point in time to continue a sync from.
        #[serde(skip_serializing_if = "Option::is_none")]
        #[ruma_api(query)]
        pub since: Option<String>,
        /// Controls whether to include the full state for all rooms the user is a member of.
        #[serde(skip_serializing_if = "Option::is_none")]
        #[ruma_api(query)]
        pub full_state: Option<bool>,
        /// Controls whether the client is automatically marked as online by polling this API.
        #[serde(skip_serializing_if = "Option::is_none")]
        #[ruma_api(query)]
        pub set_presence: Option<SetPresence>,
        /// The maximum time to poll in milliseconds before returning this request.
        #[serde(skip_serializing_if = "Option::is_none")]
        #[ruma_api(query)]
        pub timeout: Option<UInt>,
    }

    response {
        /// The batch token to supply in the `since` param of the next `/sync` request.
        pub next_batch: String,
        /// Updates to rooms.
        #[wrap_incoming]
        pub rooms: Rooms,
        /// Updates to the presence status of other users.
        #[wrap_incoming]
        pub presence: Presence,
    }
}

/// Whether to set presence or not during sync.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub enum SetPresence {
    /// Do not set the presence of the user calling this API.
    #[serde(rename = "offline")]
    Offline,
}

/// A filter represented either as its full JSON definition or the ID of a saved filter.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[allow(clippy::large_enum_variant)]
#[serde(untagged)]
pub enum Filter {
    // The filter definition needs to be (de)serialized twice because it is a URL-encoded JSON
    // string. Since #[ruma_api(query)] only does the latter and this is a very uncommon
    // setup, we implement it through custom serde logic for this specific enum variant rather than
    // adding another ruma_api attribute.
    //
    // On the deserialization side, because this is an enum with #[serde(untagged)], serde will
    // try the variants in order (https://serde.rs/enum-representations.html). That means because
    // FilterDefinition is the first variant, JSON decoding is attempted first which is almost
    // functionally equivalent to looking at whether the first symbol is a '{' as the spec says.
    // (there are probably some corner cases like leading whitespace)
    #[serde(with = "filter_def_serde")]
    /// A complete filter definition serialized to JSON.
    FilterDefinition(FilterDefinition),
    /// The ID of a filter saved on the server.
    FilterId(String),
}

/// Serialization and deserialization logic for filter definitions.
mod filter_def_serde {
    use serde::{de::Error as _, ser::Error as _, Deserialize, Deserializer, Serializer};

    use crate::r0::filter::FilterDefinition;

    /// Serialization logic for filter definitions.
    pub fn serialize<S>(filter_def: &FilterDefinition, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let string = serde_json::to_string(filter_def).map_err(S::Error::custom)?;
        serializer.serialize_str(&string)
    }

    /// Deserialization logic for filter definitions.
    pub fn deserialize<'de, D>(deserializer: D) -> Result<FilterDefinition, D::Error>
    where
        D: Deserializer<'de>,
    {
        let filter_str = <&str>::deserialize(deserializer)?;

        serde_json::from_str(filter_str).map_err(D::Error::custom)
    }
}

/// Updates to rooms.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct Rooms {
    /// The rooms that the user has left or been banned from.
    #[wrap_incoming(LeftRoom)]
    pub leave: HashMap<RoomId, LeftRoom>,
    /// The rooms that the user has joined.
    #[wrap_incoming(JoinedRoom)]
    pub join: HashMap<RoomId, JoinedRoom>,
    /// The rooms that the user has been invited to.
    #[wrap_incoming(InvitedRoom)]
    pub invite: HashMap<RoomId, InvitedRoom>,
}

/// Historical updates to left rooms.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct LeftRoom {
    /// The timeline of messages and state changes in the room up to the point when the user
    /// left.
    #[wrap_incoming]
    pub timeline: Timeline,
    /// The state updates for the room up to the start of the timeline.
    #[wrap_incoming]
    pub state: State,
}

/// Updates to joined rooms.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct JoinedRoom {
    /// Counts of unread notifications for this room.
    pub unread_notifications: UnreadNotificationsCount,
    /// The timeline of messages and state changes in the room.
    #[wrap_incoming]
    pub timeline: Timeline,
    /// Updates to the state, between the time indicated by the `since` parameter, and the start
    /// of the `timeline` (or all state up to the start of the `timeline`, if `since` is not
    /// given, or `full_state` is true).
    #[wrap_incoming]
    pub state: State,
    /// The private data that this user has attached to this room.
    #[wrap_incoming]
    pub account_data: AccountData,
    /// The ephemeral events in the room that aren't recorded in the timeline or state of the
    /// room. e.g. typing.
    #[wrap_incoming]
    pub ephemeral: Ephemeral,
}

/// unread notifications count
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct UnreadNotificationsCount {
    /// The number of unread notifications for this room with the highlight flag set.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub highlight_count: Option<UInt>,
    /// The total number of unread notifications for this room.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub notification_count: Option<UInt>,
}

/// Events in the room.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct Timeline {
    /// True if the number of events returned was limited by the `limit` on the filter.
    pub limited: bool,
    /// A token that can be supplied to to the `from` parameter of the
    /// `/rooms/{roomId}/messages` endpoint.
    pub prev_batch: String,
    /// A list of events.
    #[wrap_incoming(all::RoomEvent with EventResult)]
    pub events: Vec<all::RoomEvent>,
}

/// State events in the room.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct State {
    /// A list of state events.
    #[wrap_incoming(only::StateEvent with EventResult)]
    pub events: Vec<only::StateEvent>,
}

/// The private data that this user has attached to this room.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct AccountData {
    /// A list of events.
    #[wrap_incoming(only::Event with EventResult)]
    pub events: Vec<only::Event>,
}

/// Ephemeral events not recorded in the timeline or state of the room.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct Ephemeral {
    /// A list of events.
    #[wrap_incoming(only::Event with EventResult)]
    pub events: Vec<only::Event>,
}

/// Updates to the rooms that the user has been invited to.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct InvitedRoom {
    /// The state of a room that the user has been invited to.
    #[wrap_incoming]
    pub invite_state: InviteState,
}

/// The state of a room that the user has been invited to.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct InviteState {
    /// A list of state events.
    #[wrap_incoming(stripped::StrippedState with EventResult)]
    pub events: Vec<stripped::StrippedState>,
}

/// Updates to the presence status of other users.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct Presence {
    /// A list of events.
    #[wrap_incoming(only::Event with EventResult)]
    pub events: Vec<only::Event>,
}
<commit_msg>Limit `events` in `sync_events::Presence` to `PresenceEvent`s<commit_after>//! [GET /_matrix/client/r0/sync](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-sync)

use std::collections::HashMap;

use js_int::UInt;
use ruma_api::{ruma_api, Outgoing};
use ruma_events::{
    collections::{
        all::{RoomEvent, StateEvent},
        only::Event as NonRoomEvent,
    },
    presence::PresenceEvent,
    stripped::StrippedState,
    EventResult,
};
use ruma_identifiers::RoomId;
use serde::{Deserialize, Serialize};

use crate::r0::filter::FilterDefinition;

ruma_api! {
    metadata {
        description: "Get all new events from all rooms since the last sync or a given point of time.",
        method: GET,
        name: "sync",
        path: "/_matrix/client/r0/sync",
        rate_limited: false,
        requires_authentication: true,
    }

    request {
        /// A filter represented either as its full JSON definition or the ID of a saved filter.
        #[serde(skip_serializing_if = "Option::is_none")]
        #[ruma_api(query)]
        pub filter: Option<Filter>,
        /// A point in time to continue a sync from.
        #[serde(skip_serializing_if = "Option::is_none")]
        #[ruma_api(query)]
        pub since: Option<String>,
        /// Controls whether to include the full state for all rooms the user is a member of.
        #[serde(skip_serializing_if = "Option::is_none")]
        #[ruma_api(query)]
        pub full_state: Option<bool>,
        /// Controls whether the client is automatically marked as online by polling this API.
        #[serde(skip_serializing_if = "Option::is_none")]
        #[ruma_api(query)]
        pub set_presence: Option<SetPresence>,
        /// The maximum time to poll in milliseconds before returning this request.
        #[serde(skip_serializing_if = "Option::is_none")]
        #[ruma_api(query)]
        pub timeout: Option<UInt>,
    }

    response {
        /// The batch token to supply in the `since` param of the next `/sync` request.
        pub next_batch: String,
        /// Updates to rooms.
        #[wrap_incoming]
        pub rooms: Rooms,
        /// Updates to the presence status of other users.
        #[wrap_incoming]
        pub presence: Presence,
    }
}

/// Whether to set presence or not during sync.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub enum SetPresence {
    /// Do not set the presence of the user calling this API.
    #[serde(rename = "offline")]
    Offline,
}

/// A filter represented either as its full JSON definition or the ID of a saved filter.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[allow(clippy::large_enum_variant)]
#[serde(untagged)]
pub enum Filter {
    // The filter definition needs to be (de)serialized twice because it is a URL-encoded JSON
    // string. Since #[ruma_api(query)] only does the latter and this is a very uncommon
    // setup, we implement it through custom serde logic for this specific enum variant rather than
    // adding another ruma_api attribute.
    //
    // On the deserialization side, because this is an enum with #[serde(untagged)], serde will
    // try the variants in order (https://serde.rs/enum-representations.html). That means because
    // FilterDefinition is the first variant, JSON decoding is attempted first which is almost
    // functionally equivalent to looking at whether the first symbol is a '{' as the spec says.
    // (there are probably some corner cases like leading whitespace)
    #[serde(with = "filter_def_serde")]
    /// A complete filter definition serialized to JSON.
    FilterDefinition(FilterDefinition),
    /// The ID of a filter saved on the server.
    FilterId(String),
}

/// Serialization and deserialization logic for filter definitions.
mod filter_def_serde {
    use serde::{de::Error as _, ser::Error as _, Deserialize, Deserializer, Serializer};

    use crate::r0::filter::FilterDefinition;

    /// Serialization logic for filter definitions.
    pub fn serialize<S>(filter_def: &FilterDefinition, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let string = serde_json::to_string(filter_def).map_err(S::Error::custom)?;
        serializer.serialize_str(&string)
    }

    /// Deserialization logic for filter definitions.
    pub fn deserialize<'de, D>(deserializer: D) -> Result<FilterDefinition, D::Error>
    where
        D: Deserializer<'de>,
    {
        let filter_str = <&str>::deserialize(deserializer)?;

        serde_json::from_str(filter_str).map_err(D::Error::custom)
    }
}

/// Updates to rooms.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct Rooms {
    /// The rooms that the user has left or been banned from.
    #[wrap_incoming(LeftRoom)]
    pub leave: HashMap<RoomId, LeftRoom>,
    /// The rooms that the user has joined.
    #[wrap_incoming(JoinedRoom)]
    pub join: HashMap<RoomId, JoinedRoom>,
    /// The rooms that the user has been invited to.
    #[wrap_incoming(InvitedRoom)]
    pub invite: HashMap<RoomId, InvitedRoom>,
}

/// Historical updates to left rooms.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct LeftRoom {
    /// The timeline of messages and state changes in the room up to the point when the user
    /// left.
    #[wrap_incoming]
    pub timeline: Timeline,
    /// The state updates for the room up to the start of the timeline.
    #[wrap_incoming]
    pub state: State,
}

/// Updates to joined rooms.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct JoinedRoom {
    /// Counts of unread notifications for this room.
    pub unread_notifications: UnreadNotificationsCount,
    /// The timeline of messages and state changes in the room.
    #[wrap_incoming]
    pub timeline: Timeline,
    /// Updates to the state, between the time indicated by the `since` parameter, and the start
    /// of the `timeline` (or all state up to the start of the `timeline`, if `since` is not
    /// given, or `full_state` is true).
    #[wrap_incoming]
    pub state: State,
    /// The private data that this user has attached to this room.
    #[wrap_incoming]
    pub account_data: AccountData,
    /// The ephemeral events in the room that aren't recorded in the timeline or state of the
    /// room. e.g. typing.
    #[wrap_incoming]
    pub ephemeral: Ephemeral,
}

/// unread notifications count
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct UnreadNotificationsCount {
    /// The number of unread notifications for this room with the highlight flag set.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub highlight_count: Option<UInt>,
    /// The total number of unread notifications for this room.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub notification_count: Option<UInt>,
}

/// Events in the room.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct Timeline {
    /// True if the number of events returned was limited by the `limit` on the filter.
    pub limited: bool,
    /// A token that can be supplied to to the `from` parameter of the
    /// `/rooms/{roomId}/messages` endpoint.
    pub prev_batch: String,
    /// A list of events.
    #[wrap_incoming(RoomEvent with EventResult)]
    pub events: Vec<RoomEvent>,
}

/// State events in the room.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct State {
    /// A list of state events.
    #[wrap_incoming(StateEvent with EventResult)]
    pub events: Vec<StateEvent>,
}

/// The private data that this user has attached to this room.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct AccountData {
    /// A list of events.
    // TODO: Create
    #[wrap_incoming(NonRoomEvent with EventResult)]
    pub events: Vec<NonRoomEvent>,
}

/// Ephemeral events not recorded in the timeline or state of the room.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct Ephemeral {
    /// A list of events.
    #[wrap_incoming(NonRoomEvent with EventResult)]
    pub events: Vec<NonRoomEvent>,
}

/// Updates to the rooms that the user has been invited to.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct InvitedRoom {
    /// The state of a room that the user has been invited to.
    #[wrap_incoming]
    pub invite_state: InviteState,
}

/// The state of a room that the user has been invited to.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct InviteState {
    /// A list of state events.
    #[wrap_incoming(StrippedState with EventResult)]
    pub events: Vec<StrippedState>,
}

/// Updates to the presence status of other users.
#[derive(Clone, Debug, Serialize, Outgoing)]
pub struct Presence {
    /// A list of events.
    #[wrap_incoming(PresenceEvent with EventResult)]
    pub events: Vec<PresenceEvent>,
}
<|endoftext|>


<commit_before>#![allow(deprecated)]

/// Regression test to ensure that type aliases do not cause compilation failures.
use std::str::FromStr;

use clap::{Parser, Subcommand, ValueEnum};

// Result type alias
#[allow(dead_code)]
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;

// Wrapper to use for Option type alias
#[derive(Debug, PartialEq, Eq)]
struct Wrapper<T>(T);

impl<T: FromStr> FromStr for Wrapper<T> {
    type Err = <T as FromStr>::Err;

    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
        T::from_str(s).map(Wrapper)
    }
}

type Option<T> = std::option::Option<Wrapper<T>>;

#[derive(Parser)]
pub struct Opts {
    #[clap(value_parser)]
    another_string: String,
    #[clap(subcommand)]
    command: Command,
    #[clap(short, long, value_enum, value_parser)]
    choice: ArgChoice,
}

#[derive(Subcommand, PartialEq, Debug)]
enum Command {
    DoSomething { arg: Option<String> },
}

#[derive(ValueEnum, PartialEq, Debug, Clone)]
enum ArgChoice {
    Foo,
    Bar,
}

#[test]
fn type_alias_regressions() {
    Opts::try_parse_from(["test", "value", "--choice=foo", "do-something"]).unwrap();
}
<commit_msg>test(derive): No longer supporting some wrapped types<commit_after>//! Regression test to ensure that type aliases do not cause compilation failures.
#![allow(deprecated)]

use clap::{Parser, Subcommand, ValueEnum};

// Result type alias
#[allow(dead_code)]
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;

type Option<T> = std::option::Option<T>;

#[derive(Parser)]
pub struct Opts {
    #[clap(value_parser)]
    another_string: String,
    #[clap(subcommand)]
    command: Command,
    #[clap(short, long, value_enum, value_parser)]
    choice: ArgChoice,
}

#[derive(Subcommand, PartialEq, Debug)]
enum Command {
    DoSomething { arg: Option<String> },
}

#[derive(ValueEnum, PartialEq, Debug, Clone)]
enum ArgChoice {
    Foo,
    Bar,
}

#[test]
fn type_alias_regressions() {
    Opts::try_parse_from(["test", "value", "--choice=foo", "do-something"]).unwrap();
}
<|endoftext|>


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

use eutil::fptr_is_null;
use libc::{size_t, c_int, c_ushort,c_void};
use libc::types::os::arch::c95::wchar_t;
use mem::{new0,newarray0,delete,deletearray};
use std::mem;
use std::ptr;
use std::slice;
use std::string;
use std::str;
use types::{cef_string_utf16_t, cef_string_utf8_t, cef_string_wide_t};
use types::{cef_string_userfree_utf16_t, cef_string_userfree_utf8_t, cef_string_userfree_wide_t};

//cef_string

#[no_mangle]
extern "C" fn string_wide_dtor(str: *mut wchar_t) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
extern "C" fn string_utf8_dtor(str: *mut u8) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
extern "C" fn string_utf16_dtor(str: *mut c_ushort) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_free(cs: *mut cef_string_userfree_wide_t) {
   cef_string_wide_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_free(cs: *mut cef_string_userfree_utf8_t) {
   cef_string_utf8_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_free(cs: *mut cef_string_userfree_utf16_t) {
   cef_string_utf16_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_clear(cs: *mut cef_string_utf8_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut u8;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_alloc() -> *mut cef_string_utf8_t {
    #![inline(never)]
    new0::<cef_string_utf8_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_set(src: *const u8, src_len: size_t, output: *mut cef_string_utf8_t, copy: c_int) -> c_int {
    cef_string_utf8_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<u8>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_utf8_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_to_utf16(src: *const u8, src_len: size_t, output: *mut cef_string_utf16_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice(src, src_len as uint, |result| {
            let enc = str::from_utf8(result).unwrap().utf16_units().collect::<Vec<u16>>();
            cef_string_utf16_set(enc.as_ptr(), enc.len() as size_t, output, 1);
       });
    }
    1
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_to_utf8(src: *const u16, src_len: size_t, output: *mut cef_string_utf8_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice(src, src_len as uint, |ustr| {
            match string::String::from_utf16(ustr) {
                Some(str) => {
                    cef_string_utf8_set(str.as_bytes().as_ptr(), str.len() as size_t, output, 1);
                    return 1 as c_int;
                },
                None => {
                    return 0 as c_int;
                }
            }
       });
    }
    1
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_clear(cs: *mut cef_string_utf16_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut c_ushort;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_alloc() -> *mut cef_string_utf16_t {
    #![inline(never)]
    new0::<cef_string_utf16_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_set(src: *const c_ushort, src_len: size_t, output: *mut cef_string_utf16_t, copy: c_int) -> c_int {
    cef_string_utf16_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<c_ushort>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_utf16_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_wide_clear(cs: *mut cef_string_wide_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut wchar_t;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_alloc() -> *mut cef_string_wide_t {
    #![inline(never)]
    new0::<cef_string_wide_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_wide_set(src: *const wchar_t, src_len: size_t, output: *mut cef_string_wide_t, copy: c_int) -> c_int {
    cef_string_wide_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<wchar_t>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_wide_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}
<commit_msg>handle str::from_utf8() failure, improve return calls<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use eutil::fptr_is_null;
use libc::{size_t, c_int, c_ushort,c_void};
use libc::types::os::arch::c95::wchar_t;
use mem::{new0,newarray0,delete,deletearray};
use std::mem;
use std::ptr;
use std::slice;
use std::string;
use std::str;
use types::{cef_string_utf16_t, cef_string_utf8_t, cef_string_wide_t};
use types::{cef_string_userfree_utf16_t, cef_string_userfree_utf8_t, cef_string_userfree_wide_t};

//cef_string

#[no_mangle]
extern "C" fn string_wide_dtor(str: *mut wchar_t) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
extern "C" fn string_utf8_dtor(str: *mut u8) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
extern "C" fn string_utf16_dtor(str: *mut c_ushort) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_free(cs: *mut cef_string_userfree_wide_t) {
   cef_string_wide_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_free(cs: *mut cef_string_userfree_utf8_t) {
   cef_string_utf8_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_free(cs: *mut cef_string_userfree_utf16_t) {
   cef_string_utf16_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_clear(cs: *mut cef_string_utf8_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut u8;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_alloc() -> *mut cef_string_utf8_t {
    #![inline(never)]
    new0::<cef_string_utf8_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_set(src: *const u8, src_len: size_t, output: *mut cef_string_utf8_t, copy: c_int) -> c_int {
    cef_string_utf8_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<u8>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_utf8_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_to_utf16(src: *const u8, src_len: size_t, output: *mut cef_string_utf16_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice(src, src_len as uint, |result| {
            match str::from_utf8(result) {
                 Some(enc) => {
                      let conv = enc.utf16_units().collect::<Vec<u16>>();
                      cef_string_utf16_set(conv.as_ptr(), conv.len() as size_t, output, 1);
                      1
                 },
                 None => 0
            }
       })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_to_utf8(src: *const u16, src_len: size_t, output: *mut cef_string_utf8_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice(src, src_len as uint, |ustr| {
            match string::String::from_utf16(ustr) {
                Some(str) => {
                    cef_string_utf8_set(str.as_bytes().as_ptr(), str.len() as size_t, output, 1);
                    1 as c_int
                },
                None =>  0 as c_int
            }
       })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_clear(cs: *mut cef_string_utf16_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut c_ushort;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_alloc() -> *mut cef_string_utf16_t {
    #![inline(never)]
    new0::<cef_string_utf16_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_set(src: *const c_ushort, src_len: size_t, output: *mut cef_string_utf16_t, copy: c_int) -> c_int {
    cef_string_utf16_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<c_ushort>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_utf16_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_wide_clear(cs: *mut cef_string_wide_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut wchar_t;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_alloc() -> *mut cef_string_wide_t {
    #![inline(never)]
    new0::<cef_string_wide_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_wide_set(src: *const wchar_t, src_len: size_t, output: *mut cef_string_wide_t, copy: c_int) -> c_int {
    cef_string_wide_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<wchar_t>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_wide_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}
<|endoftext|>


<commit_before>//!
#![warn(clippy::all, rust_2018_idioms, missing_docs)]

#[cfg(feature = "runtime")]
use lazy_static::lazy_static;
#[cfg(feature = "runtime")]
use tokio::runtime::{self, Runtime};

pub use tokio_postgres::{error, row, tls, types, Column, Portal, SimpleQueryMessage, Statement};

pub use crate::client::*;
#[cfg(feature = "runtime")]
pub use crate::config::Config;
pub use crate::copy_out_reader::*;
#[doc(no_inline)]
pub use crate::error::Error;
pub use crate::query_iter::*;
pub use crate::query_portal_iter::*;
#[doc(no_inline)]
pub use crate::row::{Row, SimpleQueryRow};
pub use crate::simple_query_iter::*;
#[doc(no_inline)]
pub use crate::tls::NoTls;
pub use crate::to_statement::*;
pub use crate::transaction::*;

mod client;
#[cfg(feature = "runtime")]
pub mod config;
mod copy_out_reader;
mod query_iter;
mod query_portal_iter;
mod simple_query_iter;
mod to_statement;
mod transaction;

#[cfg(feature = "runtime")]
#[cfg(test)]
mod test;

#[cfg(feature = "runtime")]
lazy_static! {
    static ref RUNTIME: Runtime = runtime::Builder::new()
        .name_prefix("postgres-")
        .build()
        .unwrap();
}
<commit_msg>Crate level docs<commit_after>//! A synchronous client for the PostgreSQL database.
//!
//! # Example
//!
//! ```no_run
//! use postgres::{Client, NoTls};
//!
//! # fn main() -> Result<(), postgres::Error> {
//! let mut client = Client::connect("host=localhost user=postgres", NoTls)?;
//!
//! client.simple_query("
//!     CREATE TABLE person (
//!         id      SERIAL PRIMARY KEY,
//!         name    TEXT NOT NULL,
//!         data    BYTEA
//!     )
//! ")?;
//!
//! let name = "Ferris";
//! let data = None::<&[u8]>;
//! client.execute(
//!     "INSERT INTO person (name, data) VALUES ($1, $2)",
//!     &[&name, &data],
//! )?;
//!
//! for row in client.query("SELECT id, name, data FROM person", &[])? {
//!     let id: i32 = row.get(0);
//!     let name: &str = row.get(1);
//!     let data: Option<&[u8]> = row.get(2);
//!
//!     println!("found person: {} {} {:?}", id, name, data);
//! }
//! # Ok(())
//! # }
//! ```
//!
//! # Implementation
//!
//! This crate is a lightweight wrapper over tokio-postgres. The `tokio_postgres::Connection` is spawned onto an
//! executor, and the `tokio_postgres::Client` is wrapped in the `postgres::Client`, which simply waits on the futures
//! the nonblocking client creates.
//!
//! # Runtime
//!
//! A client can be constructed directly from a `tokio-postgres` client via a `From` implementation, but the `runtime`
//! Cargo feature (enabled by default) provides a more convenient interface. By default, connections will be spawned
//! onto a static tokio `Runtime`, but a custom `Executor` can also be used instead.
//!
//! # SSL/TLS support
//!
//! TLS support is implemented via external libraries. `Client::connect` and `Config::connect` take a TLS implementation
//! as an argument. The `NoTls` type in this crate can be used when TLS is not required. Otherwise, the
//! `tokio-postgres-openssl` and `tokio-postgres-native-tls` crates provide implementations backed by the `postgres` and
//! `native-tls` crates, respectively.
#![warn(clippy::all, rust_2018_idioms, missing_docs)]

#[cfg(feature = "runtime")]
use lazy_static::lazy_static;
#[cfg(feature = "runtime")]
use tokio::runtime::{self, Runtime};

pub use tokio_postgres::{error, row, tls, types, Column, Portal, SimpleQueryMessage, Statement};

pub use crate::client::*;
#[cfg(feature = "runtime")]
pub use crate::config::Config;
pub use crate::copy_out_reader::*;
#[doc(no_inline)]
pub use crate::error::Error;
pub use crate::query_iter::*;
pub use crate::query_portal_iter::*;
#[doc(no_inline)]
pub use crate::row::{Row, SimpleQueryRow};
pub use crate::simple_query_iter::*;
#[doc(no_inline)]
pub use crate::tls::NoTls;
pub use crate::to_statement::*;
pub use crate::transaction::*;

mod client;
#[cfg(feature = "runtime")]
pub mod config;
mod copy_out_reader;
mod query_iter;
mod query_portal_iter;
mod simple_query_iter;
mod to_statement;
mod transaction;

#[cfg(feature = "runtime")]
#[cfg(test)]
mod test;

#[cfg(feature = "runtime")]
lazy_static! {
    static ref RUNTIME: Runtime = runtime::Builder::new()
        .name_prefix("postgres-")
        .build()
        .unwrap();
}
<|endoftext|>


<commit_before>use std::env;

fn increase(number: i32) {
    println!("{}", number + 1);
}

fn decrease(number: i32) {
    println!("{}", number - 1);
}

fn help() {
    println!("usage:
match_args <string>
    Check whether given string is the answer.
match_args {{increase|decrease}} <integer>
    Increase or decrease given integer by one.");
}

fn main() {
    let args: Vec<String> = env::args().collect();

    match args.len() {
        // no arguments passed
        1 => {
            println!("My name is 'match_args'. Try passing some arguments!");
        },
        // one argument passed
        2 => {
            if &42 == &args[1].parse().unwrap() {
                println!("This is the answer!");
            } else {
                println!("This is not the answer.");
            }
        },
        // one command and one argument passed
        3 => {
            let cmd = &args[1];
            let num = &args[2];
            // parse the number
            let number: i32 = match num.parse() {
                Ok(n) => {
                    n
                },
                Err(_) => {
                    println!("error: second argument not an integer");
                    help();
                    return;
                },
            };
            // parse the command
            match &cmd[..] {
                "increase" => increase(number),
                "decrease" => decrease(number),
                _ => {
                    println!("error: invalid command");
                    help();
                },
            }
        },
        // all the other cases
        _ => {
            // show a help message
            help();
        }
    }
}
<commit_msg>std_misc/arg/matching: fix match_args.rs to match input.md<commit_after>use std::env;

fn increase(number: i32) {
    println!("{}", number + 1);
}

fn decrease(number: i32) {
    println!("{}", number - 1);
}

fn help() {
    println!("usage:
match_args <string>
    Check whether given string is the answer.
match_args {{increase|decrease}} <integer>
    Increase or decrease given integer by one.");
}

fn main() {
    let args: Vec<String> = env::args().collect();

    match args.len() {
        // no arguments passed
        1 => {
            println!("My name is 'match_args'. Try passing some arguments!");
        },
        // one argument passed
        2 => {
            match args[1].parse() {
                Ok(42) => println!("This is the answer!"),
                _ => println!("This is not the answer."),
            }
        },
        // one command and one argument passed
        3 => {
            let cmd = &args[1];
            let num = &args[2];
            // parse the number
            let number: i32 = match num.parse() {
                Ok(n) => {
                    n
                },
                Err(_) => {
                    println!("error: second argument not an integer");
                    help();
                    return;
                },
            };
            // parse the command
            match &cmd[..] {
                "increase" => increase(number),
                "decrease" => decrease(number),
                _ => {
                    println!("error: invalid command");
                    help();
                },
            }
        },
        // all the other cases
        _ => {
            // show a help message
            help();
        }
    }
}
<|endoftext|>


<commit_before>use crate::support::{basic_lib_manifest, project};

#[cargo_test]
fn missing_inherits() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [profile.release-lto]
            codegen-units = 7
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
[ERROR] failed to parse manifest at [..]

Caused by:
  An 'inherits' directive is needed for all profiles that are not 'dev' or 'release'. Here it is missing from 'release-lto'",
        )
        .run();
}

#[cargo_test]
fn non_existent_inherits() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [profile.release-lto]
            codegen-units = 7
            inherits = "non-existent"
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
[ERROR] failed to parse manifest at [..]

Caused by:
  Profile 'non-existent' not found in Cargo.toml",
        )
        .run();
}

#[cargo_test]
fn self_inherits() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [profile.release-lto]
            codegen-units = 7
            inherits = "release-lto"
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
[ERROR] failed to parse manifest at [..]

Caused by:
  Inheritance loop of profiles cycles with profile 'release-lto'",
        )
        .run();
}

#[cargo_test]
fn inherits_loop() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [profile.release-lto]
            codegen-units = 7
            inherits = "release-lto2"

            [profile.release-lto2]
            codegen-units = 7
            inherits = "release-lto"
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
[ERROR] failed to parse manifest at [..]

Caused by:
  Inheritance loop of profiles cycles with profile 'release-lto'",
        )
        .run();
}

#[cargo_test]
fn overrides_with_custom() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["profile-overrides", "named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [dependencies]
            xxx = {path = "xxx"}
            yyy = {path = "yyy"}

            [profile.dev]
            codegen-units = 7

            [profile.dev.overrides.xxx]
            codegen-units = 5
            [profile.dev.overrides.yyy]
            codegen-units = 3

            [profile.other]
            inherits = "dev"
            codegen-units = 2

            [profile.other.overrides.yyy]
            codegen-units = 6
        "#,
        )
        .file("src/lib.rs", "")
        .file("xxx/Cargo.toml", &basic_lib_manifest("xxx"))
        .file("xxx/src/lib.rs", "")
        .file("yyy/Cargo.toml", &basic_lib_manifest("yyy"))
        .file("yyy/src/lib.rs", "")
        .build();

    // profile overrides are inherited between profiles using inherits and have a
    // higher priority than profile options provided by custom profiles
    p.cargo("build -v")
        .masquerade_as_nightly_cargo()
        .with_stderr_unordered(
            "\
[COMPILING] xxx [..]
[COMPILING] yyy [..]
[COMPILING] foo [..]
[RUNNING] `rustc --crate-name xxx [..] -C codegen-units=5 [..]`
[RUNNING] `rustc --crate-name yyy [..] -C codegen-units=3 [..]`
[RUNNING] `rustc --crate-name foo [..] -C codegen-units=7 [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
        )
        .run();

    // This also verifies that the custom profile names appears in the finished line.
    p.cargo("build --profile=other -Z unstable-options -v")
        .masquerade_as_nightly_cargo()
        .with_stderr_unordered(
            "\
[COMPILING] xxx [..]
[COMPILING] yyy [..]
[COMPILING] foo [..]
[RUNNING] `rustc --crate-name xxx [..] -C codegen-units=5 [..]`
[RUNNING] `rustc --crate-name yyy [..] -C codegen-units=6 [..]`
[RUNNING] `rustc --crate-name foo [..] -C codegen-units=2 [..]`
[FINISHED] other [unoptimized + debuginfo] target(s) in [..]
",
        )
        .run();
}

#[cargo_test]
fn conflicting_usage() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            [package]
            name = "foo"
            version = "0.0.1"
            authors = []
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build -Z unstable-options --profile=dev --release")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr_unordered("error: Conflicting usage of --profile and --release")
        .run();

    p.cargo("install -Z unstable-options --profile=release --debug")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr_unordered("error: Conflicting usage of --profile and --debug")
        .run();
}
<commit_msg>testsuite: profile_custom - add clean_custom_dirname<commit_after>use crate::support::{basic_lib_manifest, project};

#[cargo_test]
fn missing_inherits() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [profile.release-lto]
            codegen-units = 7
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
[ERROR] failed to parse manifest at [..]

Caused by:
  An 'inherits' directive is needed for all profiles that are not 'dev' or 'release'. Here it is missing from 'release-lto'",
        )
        .run();
}

#[cargo_test]
fn non_existent_inherits() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [profile.release-lto]
            codegen-units = 7
            inherits = "non-existent"
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
[ERROR] failed to parse manifest at [..]

Caused by:
  Profile 'non-existent' not found in Cargo.toml",
        )
        .run();
}

#[cargo_test]
fn self_inherits() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [profile.release-lto]
            codegen-units = 7
            inherits = "release-lto"
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
[ERROR] failed to parse manifest at [..]

Caused by:
  Inheritance loop of profiles cycles with profile 'release-lto'",
        )
        .run();
}

#[cargo_test]
fn inherits_loop() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [profile.release-lto]
            codegen-units = 7
            inherits = "release-lto2"

            [profile.release-lto2]
            codegen-units = 7
            inherits = "release-lto"
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
[ERROR] failed to parse manifest at [..]

Caused by:
  Inheritance loop of profiles cycles with profile 'release-lto'",
        )
        .run();
}

#[cargo_test]
fn overrides_with_custom() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["profile-overrides", "named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [dependencies]
            xxx = {path = "xxx"}
            yyy = {path = "yyy"}

            [profile.dev]
            codegen-units = 7

            [profile.dev.overrides.xxx]
            codegen-units = 5
            [profile.dev.overrides.yyy]
            codegen-units = 3

            [profile.other]
            inherits = "dev"
            codegen-units = 2

            [profile.other.overrides.yyy]
            codegen-units = 6
        "#,
        )
        .file("src/lib.rs", "")
        .file("xxx/Cargo.toml", &basic_lib_manifest("xxx"))
        .file("xxx/src/lib.rs", "")
        .file("yyy/Cargo.toml", &basic_lib_manifest("yyy"))
        .file("yyy/src/lib.rs", "")
        .build();

    // profile overrides are inherited between profiles using inherits and have a
    // higher priority than profile options provided by custom profiles
    p.cargo("build -v")
        .masquerade_as_nightly_cargo()
        .with_stderr_unordered(
            "\
[COMPILING] xxx [..]
[COMPILING] yyy [..]
[COMPILING] foo [..]
[RUNNING] `rustc --crate-name xxx [..] -C codegen-units=5 [..]`
[RUNNING] `rustc --crate-name yyy [..] -C codegen-units=3 [..]`
[RUNNING] `rustc --crate-name foo [..] -C codegen-units=7 [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
        )
        .run();

    // This also verifies that the custom profile names appears in the finished line.
    p.cargo("build --profile=other -Z unstable-options -v")
        .masquerade_as_nightly_cargo()
        .with_stderr_unordered(
            "\
[COMPILING] xxx [..]
[COMPILING] yyy [..]
[COMPILING] foo [..]
[RUNNING] `rustc --crate-name xxx [..] -C codegen-units=5 [..]`
[RUNNING] `rustc --crate-name yyy [..] -C codegen-units=6 [..]`
[RUNNING] `rustc --crate-name foo [..] -C codegen-units=2 [..]`
[FINISHED] other [unoptimized + debuginfo] target(s) in [..]
",
        )
        .run();
}

#[cargo_test]
fn conflicting_usage() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            [package]
            name = "foo"
            version = "0.0.1"
            authors = []
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build -Z unstable-options --profile=dev --release")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr_unordered("error: Conflicting usage of --profile and --release")
        .run();

    p.cargo("install -Z unstable-options --profile=release --debug")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr_unordered("error: Conflicting usage of --profile and --debug")
        .run();
}

#[cargo_test]
fn clean_custom_dirname() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [profile.other]
            inherits = "release"
        "#,
        )
        .file("src/main.rs", "fn main() {}")
        .build();

    p.cargo("build --release")
        .masquerade_as_nightly_cargo()
        .run();

    p.cargo("clean -p foo").masquerade_as_nightly_cargo().run();

    p.cargo("build --release")
        .masquerade_as_nightly_cargo()
        .with_stdout("")
        .run();

    p.cargo("clean -p foo --release")
        .masquerade_as_nightly_cargo()
        .run();

    p.cargo("build --release")
        .masquerade_as_nightly_cargo()
        .with_stderr(
            "\
[COMPILING] foo v0.0.1 ([..])
[FINISHED] release [optimized] target(s) in [..]
",
        )
        .run();

    p.cargo("build").masquerade_as_nightly_cargo().run();

    p.cargo("build -Z unstable-options --profile=other")
        .masquerade_as_nightly_cargo()
        .with_stderr(
            "\
[COMPILING] foo v0.0.1 ([..])
[FINISHED] other [optimized] target(s) in [..]
",
        )
        .run();

    p.cargo("clean")
        .arg("--release")
        .masquerade_as_nightly_cargo()
        .run();

    // Make sure that 'other' was not cleaned
    assert!(p.build_dir().is_dir());
    assert!(p.build_dir().join("debug").is_dir());
    assert!(p.build_dir().join("other").is_dir());
    assert!(!p.build_dir().join("release").is_dir());

    // This should clean 'other'
    p.cargo("clean -Z unstable-options --profile=other")
        .masquerade_as_nightly_cargo()
        .with_stderr("")
        .run();
    assert!(p.build_dir().join("debug").is_dir());
    assert!(!p.build_dir().join("other").is_dir());
}
<|endoftext|>


<commit_before>#![no_std]

extern crate quick_protobuf;

mod pb_rs_nostd;

use crate::pb_rs_nostd::protos::no_std::NoStdMessage;
use quick_protobuf::{serialize_into_slice, deserialize_from_slice};

fn main() {
    let message = NoStdMessage::default();

    let mut buf = [0u8; 1024];
    serialize_into_slice(&message, &mut buf).unwrap();

    let read_message = deserialize_from_slice(&buf).unwrap();
    assert_eq!(message, read_message);
}

<commit_msg>show that compiler doesn't care about multiple extern crate from separate modules<commit_after>#![no_std]

extern crate quick_protobuf;
extern crate alloc;

mod pb_rs_nostd;

use crate::pb_rs_nostd::protos::no_std::NoStdMessage;
use quick_protobuf::{serialize_into_slice, deserialize_from_slice};

fn main() {
    let message = NoStdMessage::default();

    let mut buf = [0u8; 1024];
    serialize_into_slice(&message, &mut buf).unwrap();

    let read_message = deserialize_from_slice(&buf).unwrap();
    assert_eq!(message, read_message);
}

<|endoftext|>


<commit_before>use regex::Regex;
use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::{Path, PathBuf};

fn main() {
    let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
    let weak_linkage = match env::var("CARGO_FEATURE_WEAK_LINKAGE") {
        Ok(_) => true,
        Err(_) => false,
    };

    // Generate C++ bindings
    let mut build_config = cpp_build::Config::new();
    build_config.include("include");
    if weak_linkage {
        build_config.cpp_link_stdlib(None);
    }
    build_config.build("src/lldb.rs");

    if target_os == "windows" {
        strong_linkage();
    } else {
        if weak_linkage {
            if target_os == "macos" {
                println!("cargo:rustc-cdylib-link-arg=-undefined");
                println!("cargo:rustc-cdylib-link-arg=dynamic_lookup");
            }
        } else {
            strong_linkage();
        }
    }
}

fn strong_linkage() {
    // Find CMakeCache
    let mut path = PathBuf::from(env::var_os("OUT_DIR").unwrap());
    let cmakecache = loop {
        let f = path.with_file_name("CMakeCache.txt");
        if f.is_file() {
            break f;
        }
        if !path.pop() {
            println!("cargo:warning=Could not find CMakeCache.txt");
            return;
        }
    };
    println!("cargo:rerun-if-changed={}", cmakecache.display());
    let config = parse_cmakecache(&cmakecache);

    if let Some(value) = config.get("LLDB_LinkSearch") {
        for path in value.split_terminator(';') {
            println!("cargo:rustc-link-search=native={}", path);
        }
    } else {
        println!("cargo:warning=LLDB_LinkSearch not set");
    }

    if let Some(value) = config.get("LLDB_LinkDylib") {
        for path in value.split_terminator(';') {
            println!("cargo:rustc-link-lib=dylib={}", path);
        }
    } else {
        println!("cargo:warning=LLDB_LinkDylib not set");
    }
}

fn parse_cmakecache(cmakecache: &Path) -> HashMap<String, String> {
    let mut result = HashMap::new();
    let reader = BufReader::new(File::open(cmakecache).expect("Open file"));
    let kvregex = Regex::new("(?mx) ^ ([A-Za-z_]+) : (STRING|FILEPATH|BOOL|STATIC|INTERNAL) = (.*)").unwrap();

    for line in reader.lines() {
        let line = line.unwrap();
        if let Some(captures) = kvregex.captures(&line) {
            let key = captures.get(1).expect("Invalid format").as_str();
            let value = captures.get(3).expect("Invalid format").as_str();
            result.insert(key.into(), value.into());
        }
    }
    result
}
<commit_msg>Track lldb source changes.<commit_after>use regex::Regex;
use std::collections::HashMap;
use std::env;
use std::fs::{self, File};
use std::io::{BufRead, BufReader};
use std::path::{Path, PathBuf};

fn main() {
    let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
    let weak_linkage = match env::var("CARGO_FEATURE_WEAK_LINKAGE") {
        Ok(_) => true,
        Err(_) => false,
    };

    // Generate C++ bindings
    let mut build_config = cpp_build::Config::new();
    build_config.include("include");
    if weak_linkage {
        build_config.cpp_link_stdlib(None);
    }

    build_config.build("src/lldb.rs");
    for entry in fs::read_dir("src").unwrap() {
        println!("cargo:rerun-if-changed={}", entry.unwrap().path().display());
    }

    if target_os == "windows" {
        strong_linkage();
    } else {
        if weak_linkage {
            if target_os == "macos" {
                println!("cargo:rustc-cdylib-link-arg=-undefined");
                println!("cargo:rustc-cdylib-link-arg=dynamic_lookup");
            }
        } else {
            strong_linkage();
        }
    }
}

fn strong_linkage() {
    // Find CMakeCache
    let mut path = PathBuf::from(env::var_os("OUT_DIR").unwrap());
    let cmakecache = loop {
        let f = path.with_file_name("CMakeCache.txt");
        if f.is_file() {
            break f;
        }
        if !path.pop() {
            println!("cargo:warning=Could not find CMakeCache.txt");
            return;
        }
    };
    println!("cargo:rerun-if-changed={}", cmakecache.display());
    let config = parse_cmakecache(&cmakecache);

    if let Some(value) = config.get("LLDB_LinkSearch") {
        for path in value.split_terminator(';') {
            println!("cargo:rustc-link-search=native={}", path);
        }
    } else {
        println!("cargo:warning=LLDB_LinkSearch not set");
    }

    if let Some(value) = config.get("LLDB_LinkDylib") {
        for path in value.split_terminator(';') {
            println!("cargo:rustc-link-lib=dylib={}", path);
        }
    } else {
        println!("cargo:warning=LLDB_LinkDylib not set");
    }
}

fn parse_cmakecache(cmakecache: &Path) -> HashMap<String, String> {
    let mut result = HashMap::new();
    let reader = BufReader::new(File::open(cmakecache).expect("Open file"));
    let kvregex = Regex::new("(?mx) ^ ([A-Za-z_]+) : (STRING|FILEPATH|BOOL|STATIC|INTERNAL) = (.*)").unwrap();

    for line in reader.lines() {
        let line = line.unwrap();
        if let Some(captures) = kvregex.captures(&line) {
            let key = captures.get(1).expect("Invalid format").as_str();
            let value = captures.get(3).expect("Invalid format").as_str();
            result.insert(key.into(), value.into());
        }
    }
    result
}
<|endoftext|>


<commit_before>//! # Unit of work
//!
//! This is a very simple wrapper around an OS thread that will pop
//! messages off a queue and run some function over them.
//! Right now it doesn't really make any assumptions.

use std::thread::{self, JoinHandle};
use std::marker::PhantomData;
use worker::queue::Consumer;

/// A background worker.
///
/// This type is generic over the _context_, _message_ and _unit function_.
/// The _context_ is some mutable state the worker has access to when handling a message.
/// The idea is to capture anything that needs to outlive a single message, like a
/// database connection, in the _context_.
/// The _message_ is the submitted input that's popped off a queue.
/// The _unit function_ is the function that's run for each message on the queue.
///
/// The worker doesn't deal with errors, _panicking_ is the root of all evil and will
/// bring an application to a halt because of backpressure.
/// So instead of _ever_ calling `.unwrap()` in a unit of work, either complete a future
/// in the message with an appropriate error, or log it and move on.
pub struct Worker<C, M, F> {
    _c: PhantomData<C>,
    _m: PhantomData<M>,
    _f: PhantomData<F>,
}

impl<C, M, F> Worker<C, M, F>
    where C: 'static + Send,
          M: 'static + Send,
          F: 'static + Send + FnMut(&mut C, M) -> ()
{
    /// Spawn a new worker that will start popping messages of the given queue consumer.
    pub fn spawn(rx: Consumer<M>, ctx: C, unit: F) -> JoinHandle<()> {
        let mut ctx = ctx;
        let mut unit = unit;

        thread::spawn(move || {
            loop {
                if let Some(msg) = rx.try_pop() {
                    unit(&mut ctx, msg);
                }
            }
        })
    }
}
<commit_msg>add an example worker<commit_after>//! # Unit of work
//!
//! This is a very simple wrapper around an OS thread that will pop
//! messages off a queue and run some function over them.
//! Right now it doesn't really make any assumptions.
//!
//! # Examples
//!
//! Spawn a new worker that prints each message it receives:
//!
//! ```no_run
//! # use ::worker::queue::*;
//! # use ::worker::unit::*;
//! let (tx, rx) = QueueBuilder::<()>::new().build();
//! let handle = Worker::spawn(rx, (), |_, msg| {
//! 	println!("got a message");
//! })
//! ```

use std::thread::{self, JoinHandle};
use std::marker::PhantomData;
use worker::queue::Consumer;

/// A background worker.
///
/// This type is generic over the _context_, _message_ and _unit function_.
/// The _context_ is some mutable state the worker has access to when handling a message.
/// The idea is to capture anything that needs to outlive a single message, like a
/// database connection, in the _context_.
/// The _message_ is the submitted input that's popped off a queue.
/// The _unit function_ is the function that's run for each message on the queue.
///
/// The worker doesn't deal with errors, _panicking_ is the root of all evil and will
/// bring an application to a halt because of backpressure.
/// So instead of _ever_ calling `.unwrap()` in a unit of work, either complete a future
/// in the message with an appropriate error, or log it and move on.
pub struct Worker<C, M, F> {
    _c: PhantomData<C>,
    _m: PhantomData<M>,
    _f: PhantomData<F>,
}

impl<C, M, F> Worker<C, M, F>
    where C: 'static + Send,
          M: 'static + Send,
          F: 'static + Send + FnMut(&mut C, M) -> ()
{
    /// Spawn a new worker that will start popping messages of the given queue consumer.
    pub fn spawn(rx: Consumer<M>, ctx: C, unit: F) -> JoinHandle<()> {
        let mut ctx = ctx;
        let mut unit = unit;

        thread::spawn(move || {
            loop {
                if let Some(msg) = rx.try_pop() {
                    unit(&mut ctx, msg);
                }
            }
        })
    }
}
<|endoftext|>