<commit_before>extern mod extra;
extern mod http_client;

use extra::json;
use extra::net::url::Url;
use extra::net::url;
use std::hashmap::HashMap;
use std::str;
use std::result::{Result, Ok, Err};

use http_client::uv_http_request;
use http_client::RequestEvent;

fn main() {

    // http://ozten.com/psto/
    // https://api.github.com/repositories
    let u: Url = url::from_str("https://api.github.com/repositories").get();
    let mut request = uv_http_request(u);

    // Problem #1 a closure with state to build on the response
    // into a string
    fn mk_handleEvent(rawJson:~str) -> @fn(RequestEvent) -> () {
        return |event| {

            //rawJson = rawJson + ~"huh";

            match event {
                http_client::Error(e) => {
                    println(fmt!("Ouch... error %?", e));
                },
                http_client::Status(s) => {
                    println(fmt!("Status %?", s));
                    //let res = json::from_str(rawJson);
                    println(fmt!("Payload! %?", rawJson));
                },
                http_client::Payload(p) => {
                    let data = p.take();
                    //rawJson +=  str::from_bytes(data);

                }
            }
        };
    };

    do request.begin |event| {

    }

    // Problem #2 How to output parts of JSON after parsing
    // I think this is working...
    match json::from_str("{\"ham\": \"bone\"}") {
        Ok(obj) => {
            match obj {
                json::Object(o) => {
                    println(fmt!("Payload! %?", o.get(& ~"ham")))
                }
                _ => { println("Skipping") }
            }

        }
        Err(e) => {
            println("Error")
        }
    }

    // HashMap play - One type of Json is Object which is a
    // type over HashMap<~str, Json>
    let mut h: HashMap<~str, ~str> = HashMap::new();
    h.insert(~"foo", ~"bar");
    h.get(& ~"foo");
}<commit_msg>Figured out closure, string is not appending<commit_after>extern mod extra;
extern mod http_client;

use extra::json;
use extra::net::url::Url;
use extra::net::url;
use std::hashmap::HashMap;
use std::str;
use std::result::{Result, Ok, Err};

use http_client::uv_http_request;
use http_client::RequestEvent;

fn main() {

    // http://ozten.com/psto/
    // https://api.github.com/repositories
    let u: Url = url::from_str("https://api.github.com/repositories").get();
    let mut request = uv_http_request(u);

    do request.begin |event| {
        let mut r = "";
        match event {
            http_client::Error(e) => {
                println(fmt!("Ouch... error %?", e));
            },
            http_client::Status(s) => {
                println(fmt!("Status %?", s));
                match json::from_str(r) {
                    Ok(json) => {
                        match json {
                            json::Object(o) => {
                                println("Have at it boys")
                            }
                            json::List(l) => {
                                println("A list of Objects, perhaps")
                            }
                            _ => {
                                println("ERROR: Unrecognized JSON format")
                            }
                        }
                    }
                    Err(e) => {

                        println(fmt!("Error parsing JSON %?", e))
                    }
                }
                //println(fmt!("Payload! %?", res));
            },
            http_client::Payload(p) => {
                let data = p.take();
                //rawJson.push(str::from_bytes(data));
                //r = r + str::from_bytes(data);
                //r.push_str(str::from_bytes(data));
                r = r + str::from_bytes(data);
                println(fmt!("%?\n\n", r));

                // I think we need to know how many bytes and then
                // do the JSON parsing here...
            }
        }
    }

    // Problem #2 How to output parts of JSON after parsing
    // I think this is working...
    match json::from_str("{\"ham\": \"bone\"}") {
        Ok(obj) => {
            match obj {
                json::Object(o) => {
                    println(fmt!("Payload! %?", o.get(& ~"ham")))
                }
                _ => { println("Skipping") }
            }

        }
        Err(e) => {
            println("Error")
        }
    }

    // HashMap play - One type of Json is Object which is a
    // type over HashMap<~str, Json>
    let mut h: HashMap<~str, ~str> = HashMap::new();
    h.insert(~"foo", ~"bar");
    h.get(& ~"foo");
}<|endoftext|>


<commit_before>#![cfg(feature = "ecs")]

extern crate rusoto_core;
extern crate rusoto_ecs;

use rusoto_ecs::{Ecs, EcsClient, ListClustersRequest, ListClustersError};
use rusoto_core::Region;

#[test]
fn main() {
    let ecs = EcsClient::new(Region::UsEast1);

    // http://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ListClusters.html
    match ecs.list_clusters(ListClustersRequest::default()).sync() {
        Ok(clusters) => {
            for arn in clusters.cluster_arns.unwrap_or(vec![]) {
                println!("arn -> {:?}", arn);
            }
        }
        Err(err) => {
            panic!("Error listing container instances {:#?}", err);
        }
    }

    match ecs.list_clusters(ListClustersRequest {
        next_token: Some("bogus".to_owned()),
        ..Default::default()
    }).sync() {
        Err(ListClustersError::InvalidParameter(msg)) => {
            assert!(msg.contains("Invalid token bogus"))
        }
        _ => panic!("this should have been an InvalidParameterException ECSError"),
    }
}
<commit_msg>Show off new hyper readbufsize config in a test.<commit_after>#![cfg(feature = "ecs")]

extern crate rusoto_core;
extern crate rusoto_ecs;

use rusoto_ecs::{Ecs, EcsClient, ListClustersRequest, ListClustersError};
use rusoto_core::{Region, DefaultCredentialsProvider};
use rusoto_core::request::{HttpClient, HttpConfig};

#[test]
fn main() {
    // EcsClient configuration demonstrates setting the hyper read_buf_size option
    // to 2MB:
    let cred_provider =  DefaultCredentialsProvider::new().unwrap();
    let mut http_config_with_bigger_buffer = HttpConfig::new();
    http_config_with_bigger_buffer.read_buf_size(1024 * 1024 * 2);
    let http_provider = HttpClient::new_with_config(http_config_with_bigger_buffer).unwrap();

    let ecs = EcsClient::new_with(http_provider, cred_provider, Region::UsEast1);

    // http://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ListClusters.html
    match ecs.list_clusters(ListClustersRequest::default()).sync() {
        Ok(clusters) => {
            for arn in clusters.cluster_arns.unwrap_or(vec![]) {
                println!("arn -> {:?}", arn);
            }
        }
        Err(err) => {
            panic!("Error listing container instances {:#?}", err);
        }
    }

    match ecs.list_clusters(ListClustersRequest {
        next_token: Some("bogus".to_owned()),
        ..Default::default()
    }).sync() {
        Err(ListClustersError::InvalidParameter(msg)) => {
            assert!(msg.contains("Invalid token bogus"))
        }
        _ => panic!("this should have been an InvalidParameterException ECSError"),
    }
}
<|endoftext|>


<commit_before>/// Conversion from an [`Iterator`].
///
/// By implementing `FromIterator` for a type, you define how it will be
/// created from an iterator. This is common for types which describe a
/// collection of some kind.
///
/// [`FromIterator::from_iter()`] is rarely called explicitly, and is instead
/// used through [`Iterator::collect()`] method. See [`Iterator::collect()`]'s
/// documentation for more examples.
///
/// See also: [`IntoIterator`].
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter::FromIterator;
///
/// let five_fives = std::iter::repeat(5).take(5);
///
/// let v = Vec::from_iter(five_fives);
///
/// assert_eq!(v, vec![5, 5, 5, 5, 5]);
/// ```
///
/// Using [`Iterator::collect()`] to implicitly use `FromIterator`:
///
/// ```
/// let five_fives = std::iter::repeat(5).take(5);
///
/// let v: Vec<i32> = five_fives.collect();
///
/// assert_eq!(v, vec![5, 5, 5, 5, 5]);
/// ```
///
/// Implementing `FromIterator` for your type:
///
/// ```
/// use std::iter::FromIterator;
///
/// // A sample collection, that's just a wrapper over Vec<T>
/// #[derive(Debug)]
/// struct MyCollection(Vec<i32>);
///
/// // Let's give it some methods so we can create one and add things
/// // to it.
/// impl MyCollection {
///     fn new() -> MyCollection {
///         MyCollection(Vec::new())
///     }
///
///     fn add(&mut self, elem: i32) {
///         self.0.push(elem);
///     }
/// }
///
/// // and we'll implement FromIterator
/// impl FromIterator<i32> for MyCollection {
///     fn from_iter<I: IntoIterator<Item=i32>>(iter: I) -> Self {
///         let mut c = MyCollection::new();
///
///         for i in iter {
///             c.add(i);
///         }
///
///         c
///     }
/// }
///
/// // Now we can make a new iterator...
/// let iter = (0..5).into_iter();
///
/// // ... and make a MyCollection out of it
/// let c = MyCollection::from_iter(iter);
///
/// assert_eq!(c.0, vec![0, 1, 2, 3, 4]);
///
/// // collect works too!
///
/// let iter = (0..5).into_iter();
/// let c: MyCollection = iter.collect();
///
/// assert_eq!(c.0, vec![0, 1, 2, 3, 4]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented(
    message = "a value of type `{Self}` cannot be built from an iterator \
               over elements of type `{A}`",
    label = "value of type `{Self}` cannot be built from `std::iter::Iterator<Item={A}>`"
)]
#[rustc_diagnostic_item = "FromIterator"]
pub trait FromIterator<A>: Sized {
    /// Creates a value from an iterator.
    ///
    /// See the [module-level documentation] for more.
    ///
    /// [module-level documentation]: crate::iter
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use std::iter::FromIterator;
    ///
    /// let five_fives = std::iter::repeat(5).take(5);
    ///
    /// let v = Vec::from_iter(five_fives);
    ///
    /// assert_eq!(v, vec![5, 5, 5, 5, 5]);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
}

/// Conversion into an [`Iterator`].
///
/// By implementing `IntoIterator` for a type, you define how it will be
/// converted to an iterator. This is common for types which describe a
/// collection of some kind.
///
/// One benefit of implementing `IntoIterator` is that your type will [work
/// with Rust's `for` loop syntax](crate::iter#for-loops-and-intoiterator).
///
/// See also: [`FromIterator`].
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let v = vec![1, 2, 3];
/// let mut iter = v.into_iter();
///
/// assert_eq!(Some(1), iter.next());
/// assert_eq!(Some(2), iter.next());
/// assert_eq!(Some(3), iter.next());
/// assert_eq!(None, iter.next());
/// ```
/// Implementing `IntoIterator` for your type:
///
/// ```
/// // A sample collection, that's just a wrapper over Vec<T>
/// #[derive(Debug)]
/// struct MyCollection(Vec<i32>);
///
/// // Let's give it some methods so we can create one and add things
/// // to it.
/// impl MyCollection {
///     fn new() -> MyCollection {
///         MyCollection(Vec::new())
///     }
///
///     fn add(&mut self, elem: i32) {
///         self.0.push(elem);
///     }
/// }
///
/// // and we'll implement IntoIterator
/// impl IntoIterator for MyCollection {
///     type Item = i32;
///     type IntoIter = std::vec::IntoIter<Self::Item>;
///
///     fn into_iter(self) -> Self::IntoIter {
///         self.0.into_iter()
///     }
/// }
///
/// // Now we can make a new collection...
/// let mut c = MyCollection::new();
///
/// // ... add some stuff to it ...
/// c.add(0);
/// c.add(1);
/// c.add(2);
///
/// // ... and then turn it into an Iterator:
/// for (i, n) in c.into_iter().enumerate() {
///     assert_eq!(i as i32, n);
/// }
/// ```
///
/// It is common to use `IntoIterator` as a trait bound. This allows
/// the input collection type to change, so long as it is still an
/// iterator. Additional bounds can be specified by restricting on
/// `Item`:
///
/// ```rust
/// fn collect_as_strings<T>(collection: T) -> Vec<String>
/// where
///     T: IntoIterator,
///     T::Item: std::fmt::Debug,
/// {
///     collection
///         .into_iter()
///         .map(|item| format!("{:?}", item))
///         .collect()
/// }
/// ```
#[rustc_diagnostic_item = "IntoIterator"]
#[rustc_skip_array_during_method_dispatch]
#[stable(feature = "rust1", since = "1.0.0")]
pub trait IntoIterator {
    /// The type of the elements being iterated over.
    #[stable(feature = "rust1", since = "1.0.0")]
    type Item;

    /// Which kind of iterator are we turning this into?
    #[stable(feature = "rust1", since = "1.0.0")]
    type IntoIter: Iterator<Item = Self::Item>;

    /// Creates an iterator from a value.
    ///
    /// See the [module-level documentation] for more.
    ///
    /// [module-level documentation]: crate::iter
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// let v = vec![1, 2, 3];
    /// let mut iter = v.into_iter();
    ///
    /// assert_eq!(Some(1), iter.next());
    /// assert_eq!(Some(2), iter.next());
    /// assert_eq!(Some(3), iter.next());
    /// assert_eq!(None, iter.next());
    /// ```
    #[lang = "into_iter"]
    #[stable(feature = "rust1", since = "1.0.0")]
    fn into_iter(self) -> Self::IntoIter;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator> IntoIterator for I {
    type Item = I::Item;
    type IntoIter = I;

    #[inline]
    fn into_iter(self) -> I {
        self
    }
}

/// Extend a collection with the contents of an iterator.
///
/// Iterators produce a series of values, and collections can also be thought
/// of as a series of values. The `Extend` trait bridges this gap, allowing you
/// to extend a collection by including the contents of that iterator. When
/// extending a collection with an already existing key, that entry is updated
/// or, in the case of collections that permit multiple entries with equal
/// keys, that entry is inserted.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// // You can extend a String with some chars:
/// let mut message = String::from("The first three letters are: ");
///
/// message.extend(&['a', 'b', 'c']);
///
/// assert_eq!("abc", &message[29..32]);
/// ```
///
/// Implementing `Extend`:
///
/// ```
/// // A sample collection, that's just a wrapper over Vec<T>
/// #[derive(Debug)]
/// struct MyCollection(Vec<i32>);
///
/// // Let's give it some methods so we can create one and add things
/// // to it.
/// impl MyCollection {
///     fn new() -> MyCollection {
///         MyCollection(Vec::new())
///     }
///
///     fn add(&mut self, elem: i32) {
///         self.0.push(elem);
///     }
/// }
///
/// // since MyCollection has a list of i32s, we implement Extend for i32
/// impl Extend<i32> for MyCollection {
///
///     // This is a bit simpler with the concrete type signature: we can call
///     // extend on anything which can be turned into an Iterator which gives
///     // us i32s. Because we need i32s to put into MyCollection.
///     fn extend<T: IntoIterator<Item=i32>>(&mut self, iter: T) {
///
///         // The implementation is very straightforward: loop through the
///         // iterator, and add() each element to ourselves.
///         for elem in iter {
///             self.add(elem);
///         }
///     }
/// }
///
/// let mut c = MyCollection::new();
///
/// c.add(5);
/// c.add(6);
/// c.add(7);
///
/// // let's extend our collection with three more numbers
/// c.extend(vec![1, 2, 3]);
///
/// // we've added these elements onto the end
/// assert_eq!("MyCollection([5, 6, 7, 1, 2, 3])", format!("{:?}", c));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Extend<A> {
    /// Extends a collection with the contents of an iterator.
    ///
    /// As this is the only required method for this trait, the [trait-level] docs
    /// contain more details.
    ///
    /// [trait-level]: Extend
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// // You can extend a String with some chars:
    /// let mut message = String::from("abc");
    ///
    /// message.extend(['d', 'e', 'f'].iter());
    ///
    /// assert_eq!("abcdef", &message);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T);

    /// Extends a collection with exactly one element.
    #[unstable(feature = "extend_one", issue = "72631")]
    fn extend_one(&mut self, item: A) {
        self.extend(Some(item));
    }

    /// Reserves capacity in a collection for the given number of additional elements.
    ///
    /// The default implementation does nothing.
    #[unstable(feature = "extend_one", issue = "72631")]
    fn extend_reserve(&mut self, additional: usize) {
        let _ = additional;
    }
}

#[stable(feature = "extend_for_unit", since = "1.28.0")]
impl Extend<()> for () {
    fn extend<T: IntoIterator<Item = ()>>(&mut self, iter: T) {
        iter.into_iter().for_each(drop)
    }
    fn extend_one(&mut self, _item: ()) {}
}

#[stable(feature = "extend_for_tuple", since = "1.56.0")]
impl<A, B, ExtendA, ExtendB> Extend<(A, B)> for (ExtendA, ExtendB)
where
    ExtendA: Extend<A>,
    ExtendB: Extend<B>,
{
    /// Allows to `extend` a tuple of collections that also implement `Extend`.
    ///
    /// See also: [`Iterator::unzip`]
    ///
    /// # Examples
    /// ```
    /// let mut tuple = (vec![0], vec![1]);
    /// tuple.extend(vec![(2, 3), (4, 5), (6, 7)]);
    /// assert_eq!(tuple.0, vec![0, 2, 4, 6]);
    /// assert_eq!(tuple.1, vec![1, 3, 5, 7]);
    ///
    /// // also allows for arbitrarily nested tuples
    /// let mut nested_tuple = (vec![(1, -1)], vec![(2, -2)]);
    /// nested_tuple.extend(vec![((3, -3), (4, -4)), ((5, -5), (6, -6))]);
    ///
    /// assert_eq!(nested_tuple.0, vec![(1, -1), (3, -3), (5, -5)]);
    /// assert_eq!(nested_tuple.1, vec![(2, -2), (4, -4), (6, -6)]);
    /// ```
    fn extend<T: IntoIterator<Item = (A, B)>>(&mut self, into_iter: T) {
        let (a, b) = self;
        let iter = into_iter.into_iter();

        fn extend<'a, A, B>(
            a: &'a mut impl Extend<A>,
            b: &'a mut impl Extend<B>,
        ) -> impl FnMut((), (A, B)) + 'a {
            move |(), (t, u)| {
                a.extend_one(t);
                b.extend_one(u);
            }
        }

        let (lower_bound, _) = iter.size_hint();
        if lower_bound > 0 {
            a.extend_reserve(lower_bound);
            b.extend_reserve(lower_bound);
        }

        iter.fold((), extend(a, b));
    }

    fn extend_one(&mut self, item: (A, B)) {
        self.0.extend_one(item.0);
        self.1.extend_one(item.1);
    }

    fn extend_reserve(&mut self, additional: usize) {
        self.0.extend_reserve(additional);
        self.1.extend_reserve(additional);
    }
}
<commit_msg>Auto merge of #88122 - Seppel3210:master, r=dtolnay<commit_after>/// Conversion from an [`Iterator`].
///
/// By implementing `FromIterator` for a type, you define how it will be
/// created from an iterator. This is common for types which describe a
/// collection of some kind.
///
/// [`FromIterator::from_iter()`] is rarely called explicitly, and is instead
/// used through [`Iterator::collect()`] method. See [`Iterator::collect()`]'s
/// documentation for more examples.
///
/// See also: [`IntoIterator`].
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter::FromIterator;
///
/// let five_fives = std::iter::repeat(5).take(5);
///
/// let v = Vec::from_iter(five_fives);
///
/// assert_eq!(v, vec![5, 5, 5, 5, 5]);
/// ```
///
/// Using [`Iterator::collect()`] to implicitly use `FromIterator`:
///
/// ```
/// let five_fives = std::iter::repeat(5).take(5);
///
/// let v: Vec<i32> = five_fives.collect();
///
/// assert_eq!(v, vec![5, 5, 5, 5, 5]);
/// ```
///
/// Implementing `FromIterator` for your type:
///
/// ```
/// use std::iter::FromIterator;
///
/// // A sample collection, that's just a wrapper over Vec<T>
/// #[derive(Debug)]
/// struct MyCollection(Vec<i32>);
///
/// // Let's give it some methods so we can create one and add things
/// // to it.
/// impl MyCollection {
///     fn new() -> MyCollection {
///         MyCollection(Vec::new())
///     }
///
///     fn add(&mut self, elem: i32) {
///         self.0.push(elem);
///     }
/// }
///
/// // and we'll implement FromIterator
/// impl FromIterator<i32> for MyCollection {
///     fn from_iter<I: IntoIterator<Item=i32>>(iter: I) -> Self {
///         let mut c = MyCollection::new();
///
///         for i in iter {
///             c.add(i);
///         }
///
///         c
///     }
/// }
///
/// // Now we can make a new iterator...
/// let iter = (0..5).into_iter();
///
/// // ... and make a MyCollection out of it
/// let c = MyCollection::from_iter(iter);
///
/// assert_eq!(c.0, vec![0, 1, 2, 3, 4]);
///
/// // collect works too!
///
/// let iter = (0..5).into_iter();
/// let c: MyCollection = iter.collect();
///
/// assert_eq!(c.0, vec![0, 1, 2, 3, 4]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented(
    message = "a value of type `{Self}` cannot be built from an iterator \
               over elements of type `{A}`",
    label = "value of type `{Self}` cannot be built from `std::iter::Iterator<Item={A}>`"
)]
#[rustc_diagnostic_item = "FromIterator"]
pub trait FromIterator<A>: Sized {
    /// Creates a value from an iterator.
    ///
    /// See the [module-level documentation] for more.
    ///
    /// [module-level documentation]: crate::iter
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use std::iter::FromIterator;
    ///
    /// let five_fives = std::iter::repeat(5).take(5);
    ///
    /// let v = Vec::from_iter(five_fives);
    ///
    /// assert_eq!(v, vec![5, 5, 5, 5, 5]);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
}

/// Conversion into an [`Iterator`].
///
/// By implementing `IntoIterator` for a type, you define how it will be
/// converted to an iterator. This is common for types which describe a
/// collection of some kind.
///
/// One benefit of implementing `IntoIterator` is that your type will [work
/// with Rust's `for` loop syntax](crate::iter#for-loops-and-intoiterator).
///
/// See also: [`FromIterator`].
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let v = vec![1, 2, 3];
/// let mut iter = v.into_iter();
///
/// assert_eq!(Some(1), iter.next());
/// assert_eq!(Some(2), iter.next());
/// assert_eq!(Some(3), iter.next());
/// assert_eq!(None, iter.next());
/// ```
/// Implementing `IntoIterator` for your type:
///
/// ```
/// // A sample collection, that's just a wrapper over Vec<T>
/// #[derive(Debug)]
/// struct MyCollection(Vec<i32>);
///
/// // Let's give it some methods so we can create one and add things
/// // to it.
/// impl MyCollection {
///     fn new() -> MyCollection {
///         MyCollection(Vec::new())
///     }
///
///     fn add(&mut self, elem: i32) {
///         self.0.push(elem);
///     }
/// }
///
/// // and we'll implement IntoIterator
/// impl IntoIterator for MyCollection {
///     type Item = i32;
///     type IntoIter = std::vec::IntoIter<Self::Item>;
///
///     fn into_iter(self) -> Self::IntoIter {
///         self.0.into_iter()
///     }
/// }
///
/// // Now we can make a new collection...
/// let mut c = MyCollection::new();
///
/// // ... add some stuff to it ...
/// c.add(0);
/// c.add(1);
/// c.add(2);
///
/// // ... and then turn it into an Iterator:
/// for (i, n) in c.into_iter().enumerate() {
///     assert_eq!(i as i32, n);
/// }
/// ```
///
/// It is common to use `IntoIterator` as a trait bound. This allows
/// the input collection type to change, so long as it is still an
/// iterator. Additional bounds can be specified by restricting on
/// `Item`:
///
/// ```rust
/// fn collect_as_strings<T>(collection: T) -> Vec<String>
/// where
///     T: IntoIterator,
///     T::Item: std::fmt::Debug,
/// {
///     collection
///         .into_iter()
///         .map(|item| format!("{:?}", item))
///         .collect()
/// }
/// ```
#[rustc_diagnostic_item = "IntoIterator"]
#[rustc_skip_array_during_method_dispatch]
#[stable(feature = "rust1", since = "1.0.0")]
pub trait IntoIterator {
    /// The type of the elements being iterated over.
    #[stable(feature = "rust1", since = "1.0.0")]
    type Item;

    /// Which kind of iterator are we turning this into?
    #[stable(feature = "rust1", since = "1.0.0")]
    type IntoIter: Iterator<Item = Self::Item>;

    /// Creates an iterator from a value.
    ///
    /// See the [module-level documentation] for more.
    ///
    /// [module-level documentation]: crate::iter
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// let v = vec![1, 2, 3];
    /// let mut iter = v.into_iter();
    ///
    /// assert_eq!(Some(1), iter.next());
    /// assert_eq!(Some(2), iter.next());
    /// assert_eq!(Some(3), iter.next());
    /// assert_eq!(None, iter.next());
    /// ```
    #[lang = "into_iter"]
    #[stable(feature = "rust1", since = "1.0.0")]
    fn into_iter(self) -> Self::IntoIter;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator> IntoIterator for I {
    type Item = I::Item;
    type IntoIter = I;

    #[inline]
    fn into_iter(self) -> I {
        self
    }
}

/// Extend a collection with the contents of an iterator.
///
/// Iterators produce a series of values, and collections can also be thought
/// of as a series of values. The `Extend` trait bridges this gap, allowing you
/// to extend a collection by including the contents of that iterator. When
/// extending a collection with an already existing key, that entry is updated
/// or, in the case of collections that permit multiple entries with equal
/// keys, that entry is inserted.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// // You can extend a String with some chars:
/// let mut message = String::from("The first three letters are: ");
///
/// message.extend(&['a', 'b', 'c']);
///
/// assert_eq!("abc", &message[29..32]);
/// ```
///
/// Implementing `Extend`:
///
/// ```
/// // A sample collection, that's just a wrapper over Vec<T>
/// #[derive(Debug)]
/// struct MyCollection(Vec<i32>);
///
/// // Let's give it some methods so we can create one and add things
/// // to it.
/// impl MyCollection {
///     fn new() -> MyCollection {
///         MyCollection(Vec::new())
///     }
///
///     fn add(&mut self, elem: i32) {
///         self.0.push(elem);
///     }
/// }
///
/// // since MyCollection has a list of i32s, we implement Extend for i32
/// impl Extend<i32> for MyCollection {
///
///     // This is a bit simpler with the concrete type signature: we can call
///     // extend on anything which can be turned into an Iterator which gives
///     // us i32s. Because we need i32s to put into MyCollection.
///     fn extend<T: IntoIterator<Item=i32>>(&mut self, iter: T) {
///
///         // The implementation is very straightforward: loop through the
///         // iterator, and add() each element to ourselves.
///         for elem in iter {
///             self.add(elem);
///         }
///     }
/// }
///
/// let mut c = MyCollection::new();
///
/// c.add(5);
/// c.add(6);
/// c.add(7);
///
/// // let's extend our collection with three more numbers
/// c.extend(vec![1, 2, 3]);
///
/// // we've added these elements onto the end
/// assert_eq!("MyCollection([5, 6, 7, 1, 2, 3])", format!("{:?}", c));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Extend<A> {
    /// Extends a collection with the contents of an iterator.
    ///
    /// As this is the only required method for this trait, the [trait-level] docs
    /// contain more details.
    ///
    /// [trait-level]: Extend
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// // You can extend a String with some chars:
    /// let mut message = String::from("abc");
    ///
    /// message.extend(['d', 'e', 'f'].iter());
    ///
    /// assert_eq!("abcdef", &message);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T);

    /// Extends a collection with exactly one element.
    #[unstable(feature = "extend_one", issue = "72631")]
    fn extend_one(&mut self, item: A) {
        self.extend(Some(item));
    }

    /// Reserves capacity in a collection for the given number of additional elements.
    ///
    /// The default implementation does nothing.
    #[unstable(feature = "extend_one", issue = "72631")]
    fn extend_reserve(&mut self, additional: usize) {
        let _ = additional;
    }
}

#[stable(feature = "extend_for_unit", since = "1.28.0")]
impl Extend<()> for () {
    fn extend<T: IntoIterator<Item = ()>>(&mut self, iter: T) {
        iter.into_iter().for_each(drop)
    }
    fn extend_one(&mut self, _item: ()) {}
}

#[stable(feature = "extend_for_tuple", since = "1.56.0")]
impl<A, B, ExtendA, ExtendB> Extend<(A, B)> for (ExtendA, ExtendB)
where
    ExtendA: Extend<A>,
    ExtendB: Extend<B>,
{
    /// Allows to `extend` a tuple of collections that also implement `Extend`.
    ///
    /// See also: [`Iterator::unzip`]
    ///
    /// # Examples
    /// ```
    /// let mut tuple = (vec![0], vec![1]);
    /// tuple.extend([(2, 3), (4, 5), (6, 7)]);
    /// assert_eq!(tuple.0, [0, 2, 4, 6]);
    /// assert_eq!(tuple.1, [1, 3, 5, 7]);
    ///
    /// // also allows for arbitrarily nested tuples as elements
    /// let mut nested_tuple = (vec![1], (vec![2], vec![3]));
    /// nested_tuple.extend([(4, (5, 6)), (7, (8, 9))]);
    ///
    /// let (a, (b, c)) = nested_tuple;
    /// assert_eq!(a, [1, 4, 7]);
    /// assert_eq!(b, [2, 5, 8]);
    /// assert_eq!(c, [3, 6, 9]);
    /// ```
    fn extend<T: IntoIterator<Item = (A, B)>>(&mut self, into_iter: T) {
        let (a, b) = self;
        let iter = into_iter.into_iter();

        fn extend<'a, A, B>(
            a: &'a mut impl Extend<A>,
            b: &'a mut impl Extend<B>,
        ) -> impl FnMut((), (A, B)) + 'a {
            move |(), (t, u)| {
                a.extend_one(t);
                b.extend_one(u);
            }
        }

        let (lower_bound, _) = iter.size_hint();
        if lower_bound > 0 {
            a.extend_reserve(lower_bound);
            b.extend_reserve(lower_bound);
        }

        iter.fold((), extend(a, b));
    }

    fn extend_one(&mut self, item: (A, B)) {
        self.0.extend_one(item.0);
        self.1.extend_one(item.1);
    }

    fn extend_reserve(&mut self, additional: usize) {
        self.0.extend_reserve(additional);
        self.1.extend_reserve(additional);
    }
}
<|endoftext|>


<commit_before>
use serialize::json;
use serialize::json::{Json, ToJson};

use valico::{
    Builder,
    MutableJson
};

pub fn test_result(params: &Builder, body: &str) -> Json {
    let obj = json::from_str(body);
    match obj {
        Ok(mut json) => {
            match params.process(json.as_object_mut().unwrap()) {
                Ok(()) => {
                    return json;
                },
                Err(err) => {
                    panic!("Error during process: {}", err.to_json().to_pretty_str());
                }
            }
        },
        Err(_) => {
            panic!("Invalid JSON");
        }
    }
}

pub fn test_error(params: &Builder, body: &str) -> Json {
    let obj = json::from_str(body);
    match obj {
        Ok(mut json) => {
            match params.process(json.as_object_mut().unwrap()) {
                Ok(()) => {
                    panic!("Success responce when we await some errors");
                },
                Err(err) => {
                    return err.to_json();
                }
            }
        },
        Err(_) => {
            panic!("Invalid JSON");
        }
    }
}

pub fn assert_str_eq(params: &Builder, body: &str, res: &str) {
    assert_eq!(test_result(params, body).to_string(), res.to_string());
}

pub fn assert_path(obj: &Json, path: &[&str]) {
    let path: Vec<String> = path.iter().map(|s| s.to_string()).collect();
    let mut ver_ref = vec![];
    for p in path.iter() {
        ver_ref.push(p);
    }
    assert!(obj.find_path(ver_ref.as_slice()).is_some());
}

pub fn assert_result_key(params: &Builder, body: &str, path: &[&str]) {
    assert_path(&test_result(params, body), path);
}

pub fn assert_error_key(params: &Builder, body: &str, path: &[&str]) {
    assert_path(&test_error(params, body), path);
}<commit_msg>refactor: rustup<commit_after>
use serialize::json;
use serialize::json::{Json, ToJson};

use valico::{
    Builder,
    MutableJson
};

pub fn test_result(params: &Builder, body: &str) -> Json {
    let obj = json::from_str(body);
    match obj {
        Ok(mut json) => {
            match params.process(json.as_object_mut().unwrap()) {
                Ok(()) => {
                    return json;
                },
                Err(err) => {
                    panic!("Error during process: {}", err.to_json().to_pretty_str());
                }
            }
        },
        Err(_) => {
            panic!("Invalid JSON");
        }
    }
}

pub fn test_error(params: &Builder, body: &str) -> Json {
    let obj = json::from_str(body);
    match obj {
        Ok(mut json) => {
            match params.process(json.as_object_mut().unwrap()) {
                Ok(()) => {
                    panic!("Success responce when we await some errors");
                },
                Err(err) => {
                    return err.to_json();
                }
            }
        },
        Err(_) => {
            panic!("Invalid JSON");
        }
    }
}

pub fn assert_str_eq(params: &Builder, body: &str, res: &str) {
    assert_eq!(test_result(params, body).to_string(), res.to_string());
}

pub fn assert_path(obj: &Json, path: &[&str]) {
    assert!(obj.find_path(path).is_some());
}

pub fn assert_result_key(params: &Builder, body: &str, path: &[&str]) {
    assert_path(&test_result(params, body), path);
}

pub fn assert_error_key(params: &Builder, body: &str, path: &[&str]) {
    assert_path(&test_error(params, body), path);
}<|endoftext|>


<commit_before>
<commit_msg>Delete a.rs<commit_after><|endoftext|>


<commit_before>#![allow(non_snake_case)]
enum r8 { // 8-bit registers
    A, // the Accumulator
    F, // Flags
    B, // General-purpose registers
    C,
    D,
    E,
    H,
    L,
}

#![allow(non_snake_case)]
enum r16 { // 16-bit registers
    AF, // General-purpose registers
    BC,
    DE,
    HL,
    SP, // the Stack Pointer
    PC, // the Program Counter
}

#![allow(non_snake_case)]
enum Flags {
    // src: http://marc.rawer.de/Gameboy/Docs/GBCPUman.pdf
    Z = 0x7, // set when a math operation results in 0 or by the CP instruction
    N = 0x6, // set if the last math instruction was subtraction
    H = 0x5, // set if a carry occurred from the lower nibble in the last math operation
    C = 0x4, // set if a carry occurred from the last math operation or if A is the smaller value when using the CP instruction
}

#![allow(non_snake_case)]
enum RawOpcode {
    // src: http://pastraiser.com/cpu/gameboy/gameboy_opcodes.html
    NOP = 0x00, // No-op
    LD_BC_d16 = 0x01, // Load the next two bytes into BC
    LD_BC_A = 0x02, // Load the value in A into BC
    INC_BC = 0x03, // Increment BC by 1
    INC_B = 0x04, // Increment B by 1
    DEC_B = 0x05, // Decrement B by 1
    LD_B_d8 = 0x06, // Load the next byte into B
    RLCA = 0x07, // Rotate register A left by 1 bit, treating the C flag as the leftmost bit
    LD_a16_SP = 0x08, // Store SP into addresses a16 (LSB) and a16+1 (MSB)
    ADD_HL_BC = 0x09, // Add the value in BC to HL
    LD_A_BC = 0x0a, // Treat BC as a pointer and load the value from memory into A
    DEC_BC = 0x0b, // Decrement BC by 1
    INC_C = 0x0c, // Increment C by 1
    DEC_C = 0x0d, // Decrement C by 1
    LD_C_d8 = 0x0e, // Load the next byte into C
    RRCA = 0x0f, // Rotate A right by 1 bit, treating the C flag as the rightmost bit
}
<commit_msg>transcribed some instructions<commit_after>#![allow(non_snake_case)]
enum r8 { // 8-bit registers
    A, // the Accumulator
    F, // Flags
    B, // General-purpose registers
    C,
    D,
    E,
    H,
    L,
}

#![allow(non_snake_case)]
enum r16 { // 16-bit registers
    AF, // General-purpose registers
    BC,
    DE,
    HL,
    SP, // the Stack Pointer
    PC, // the Program Counter
}

#![allow(non_snake_case)]
enum Flags {
    // src: http://marc.rawer.de/Gameboy/Docs/GBCPUman.pdf
    Z = 0x7, // set when a math operation results in 0 or by the CP instruction
    N = 0x6, // set if the last math instruction was subtraction
    H = 0x5, // set if a carry occurred from the lower nibble in the last math operation
    C = 0x4, // set if a carry occurred from the last math operation or if A is the smaller value when using the CP instruction
}

#![allow(non_snake_case)]
enum RawOpcode {
    // src: http://pastraiser.com/cpu/gameboy/gameboy_opcodes.html
    //                             len cycles| z n h c | description
    NOP = 0x00, //                  1     4  | - - - - | No-op
    LD_BC_d16 = 0x01, //            3    12  | - - - - | Load the next two bytes into BC
    LD_BC_A = 0x02, //              1     8  | - - - - | Load the value in A into BC
    INC_BC = 0x03, //               1     8  | - - - - | Increment BC by 1
    INC_B = 0x04, //                1     4  | Z 0 H - | Increment B by 1
    DEC_B = 0x05, //                1     4  | Z 1 H - | Decrement B by 1
    LD_B_d8 = 0x06, //              2     8  | - - - - | Load the next byte into B
    RLCA = 0x07, //                 1     4  | 0 0 0 C | Rotate register A left by 1 bit, treating the C flag as the leftmost bit
    LD_a16_SP = 0x08, //            3    20  | - - - - | Store SP into addresses a16 (LSB) and a16+1 (MSB)
    ADD_HL_BC = 0x09, //            1     8  | - 0 H C | Add the value in BC to HL
    LD_A_BC = 0x0a, //              1     8  | - - - - | Treat BC as a pointer and load the value from memory into A
    DEC_BC = 0x0b, //               1     8  | - - - - | Decrement BC by 1
    INC_C = 0x0c, //                1     4  | Z 0 H - | Increment C by 1
    DEC_C = 0x0d, //                1     4  | Z 1 H - | Decrement C by 1
    LD_C_d8 = 0x0e, //              2     8  | - - - - | Load the next byte into C
    RRCA = 0x0f, //                 1     4  | 0 0 0 C | Rotate A right by 1 bit, treating the C flag as the rightmost bit

    STOP_0 = 0x10, //               2     4  | - - - - | Enter low-power mode. Next byte is expected to be 0x00
    LD_DE_d16 = 0x11, //            3    12  | - - - - | Load the next two bytes into DE
    LD_DE_A = 0x12, //              1     8  | - - - - | Load the value in A into BC
    INC_DE = 0x13, //               1     4  | - - - - | Increment DE by 1
    INC_D = 0x14, //                1     4  | Z 0 H - | Increment D by 1
    DEC_D = 0x15, //                1     4  | Z 1 H - | Decrement D by 1
    LD_D_d8 = 0x16, //              2     8  | - - - - | Load the next byte into D
    RLA = 0x17, //                  1     4  | 0 0 0 C | Rotate A left by 1 bit, moving the C flag into the rightmost bit and the leftmost into the C flag
    JR_d8 = 0x18, //                2     8  | - - - - | With the next byte as a signed int, add it to the current address and jump to it
    ADD_HL_DE = 0x19, //            1     8  | - 0 H C | Add the value in DE to HL
    LD_A_DE = 0x1a, //              1     8  | - - - - | Treat the value in DE as a pointer and load the value from memory into A
    DEC_DE = 0x1b, //               1     8  | - - - - | Decrement DE by 1
    INC_E = 0x1c, //                1     4  | Z 0 H - | Increment E by 1
    DEC_E = 0x1d, //                1     4  | Z 1 H - | Decrement E by 1
    LD_E_d8 = 0x1e, //              2     8  | - - - - | Load the next byte into E
    RRA = 0x1f, //                  1     4  | 0 0 0 C | Rotate A right by 1 bit, moving the C flag into the rightmost bit and the leftmost into the C flag

    JR_NZ_r8 = 0x20, //             2  12/8  | - - - - | Jump relative (see 0x18 JR_d8) if the Z flag is not set
    LD_HL_d16 = 0x21, //            3    12  | - - - - | Load the next two bytes into HL
    LD_HLp_A = 0x22, //             1     8  | - - - - | Store value in register A into byte pointed by HL and post-increment HL
    INC_HL = 0x23, //               1     4  | - - - - | Increment DE by 1
    INC_H = 0x24, //                1     4  | Z 0 H - | Increment H by 1
    DEC_H = 0x25, //                1     4  | Z 1 H - | Decrement H by 1
    LD_H_d8 = 0x26, //              2     8  | - - - - | Load the next byte into H
    DAA = 0x27, //                  1     4  | Z - 0 C | Decimal adjust register A to get a correct BCD representation after an arithmetic instruction
    JR_Z_d8 = 0x28, //              2  12/8  | - - - - | Jump relative (see 0x18 JR_d8) if the Z flag is set
    ADD_HL_HL = 0x29, //            1     8  | - 0 H C | Add the value in HL to itself
    LD_A_HLp = 0x2a, //             1     8  | - - - - | Load value into register A from byte pointed by HL and post-increment HL
    DEC_HL = 0x2b, //               1     8  | - - - - | Decrement HL by 1
    INC_L = 0x2c, //                1     4  | Z 0 H - | Increment L by 1
    DEC_L = 0x2d, //                1     4  | Z 1 H - | Decrement L by 1
    LD_L_d8 = 0x2e, //              2     8  | - - - - | Load the next byte into L
    CPL = 0x2f, //                  1     4  | - 1 1 - | Take the bitwise compliment of A (A = ~A)

    JR_NC_r8 = 0x30, //             2  12/8  | - - - - | Jump relative (see 0x18 JR_d8) if the C flag is not set
    LD_SP_d16 = 0x31, //            3    12  | - - - - | Load the next two bytes into SP
    LD_HLm_A = 0x32, //             1     8  | - - - - | Store value in register A into byte pointed by HL and post-decrement HL
    INC_SP = 0x33, //               1     4  | - - - - | Increment SP by 1
    INC_ptrHL = 0x34, //            1    12  | Z 0 H - | Treat HL as a pointer and increment the value by 1
    DEC_ptrHL = 0x35, //            1    12  | Z 1 H - | Treat HL as a pointer and decrement the value by 1
    LD_ptrHL_d8 = 0x36, //          2    12  | - - - - | Treat HL as a pointer and load the next byte into its value
    SCF = 0x37, //                  1     4  | - 0 0 1 | Set the carry flag
    JR_C_d8 = 0x38, //              2  12/8  | - - - - | Jump relative (see 0x18 JR_d8) if the C flag is set
    ADD_HL_SP = 0x29, //            1     8  | - 0 H C | Add the value in SP to HL
    LD_A_HLm = 0x2a, //             1     8  | - - - - | Load value into register A from byte pointed by HL and post-decrement HL
    DEC_SP = 0x2b, //               1     8  | - - - - | Decrement SP by 1
    INC_A = 0x2c, //                1     4  | Z 0 H - | Increment A by 1
    DEC_A = 0x2d, //                1     4  | Z 1 H - | Decrement A by 1
    LD_A_d8 = 0x2e, //              2     8  | - - - - | Load the next byte into A
    CCF = 0x2f, //                  1     4  | - 0 0 C | Take the bitwise compliment of the C flag (C = ~C)
}
<|endoftext|>


<commit_before>use std::error::Error;
use std::io::prelude::*;
use std::process::{Command, Stdio};

static PANGRAM: &'static str =
"the quick brown fox jumped over the lazy dog\n";

fn main() {
    // Spawn the `wc` command
    let process = match Command::new("wc")
                                .stdin(Stdio::piped())
                                .stdout(Stdio::piped())
                                .spawn() {
        Err(why) => panic!("couldn't spawn wc: {}", Error::description(&why)),
        Ok(process) => process,
    };

    {
        // Write a string to the `stdin` of `wc`.
        //
        // `stdin` has type `Option<ChildStdin>`, but since we know this instance
        // must have one, we can directly `unwrap` it.
        match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) {
            Err(why) => panic!("couldn't write to wc stdin: {}",
                               Error::description(&why)),
            Ok(_) => println!("sent pangram to wc"),
        }

        // `stdin` gets `drop`ed here, and the pipe is closed.
        //
        // This is very important, otherwise `wc` wouldn't start processing the
        // input we just sent.
    }

    // The `stdout` field also has type `Option<ChildStdout>` so must be unwrapped.
    let mut s = String::new();
    match process.stdout.unwrap().read_to_string(&mut s) {
        Err(why) => panic!("couldn't read wc stdout: {}",
                           Error::description(&why)),
        Ok(_) => print!("wc responded with:\n{}", s),
    }
}
<commit_msg>std_misc/process/pipe: remove unnecessary enclosing block<commit_after>use std::error::Error;
use std::io::prelude::*;
use std::process::{Command, Stdio};

static PANGRAM: &'static str =
"the quick brown fox jumped over the lazy dog\n";

fn main() {
    // Spawn the `wc` command
    let process = match Command::new("wc")
                                .stdin(Stdio::piped())
                                .stdout(Stdio::piped())
                                .spawn() {
        Err(why) => panic!("couldn't spawn wc: {}", Error::description(&why)),
        Ok(process) => process,
    };

    // Write a string to the `stdin` of `wc`.
    //
    // `stdin` has type `Option<ChildStdin>`, but since we know this instance
    // must have one, we can directly `unwrap` it.
    match process.stdin.unwrap().write_all(PANGRAM.as_bytes()) {
        Err(why) => panic!("couldn't write to wc stdin: {}",
                           Error::description(&why)),
        Ok(_) => println!("sent pangram to wc"),
    }

    // Because `stdin` does not live after the above calls, it is `drop`ed,
    // and the pipe is closed.
    //
    // This is very important, otherwise `wc` wouldn't start processing the
    // input we just sent.

    // The `stdout` field also has type `Option<ChildStdout>` so must be unwrapped.
    let mut s = String::new();
    match process.stdout.unwrap().read_to_string(&mut s) {
        Err(why) => panic!("couldn't read wc stdout: {}",
                           Error::description(&why)),
        Ok(_) => print!("wc responded with:\n{}", s),
    }
}
<|endoftext|>


<commit_before>endogenous ewma epinfma  zcapf rkf kf pkf cf invef yf labf wf rrf mc zcap rk k pk c inve y lab pinf w r a
b g qs  ms  spinf sw kpf kp

endogenous labobs robs pinfobs dy dc dinve dw

endogenous dr pinf_target

exogenous ea eb eg  eqs  em  epinf ew

parameters curvw cgy curvp constelab constepinf constebeta cmaw cmap calfa
czcap csadjcost ctou csigma chabb cfc
cindw cprobw cindp cprobp csigl clandaw  crpi crdy cry crr
crhoa crhoas crhob crhog crhols crhoqs crhoms crhopinf crhow
ctrend cg, sig_a, sig_b,sig_w,sig_pinf,sig_m,sig_qs,sig_g

% loss function weights
parameters wy, wr

% we begin by specifying the transition probabilities
parameters pelin_tp_1_2, pelin_tp_2_1

model(linear)

		# cpie=1+constepinf/100;
		# cgamma=1+ctrend/100 ;
		# cbeta=1/(1+constebeta/100);
		# clandap=cfc;
		# cbetabar=cbeta*cgamma^(-csigma);
		# cr=cpie/(cbeta*cgamma^(-csigma));
		# crk=(cbeta^(-1))*(cgamma^csigma) - (1-ctou);
		# cw = (calfa^calfa*(1-calfa)^(1-calfa)/(clandap*crk^calfa))^(1/(1-calfa));
		# cikbar=(1-(1-ctou)/cgamma);
		# cik=(1-(1-ctou)/cgamma)*cgamma;
		# clk=((1-calfa)/calfa)*(crk/cw);
		# cky=cfc*(clk)^(calfa-1);
		# ciy=cik*cky;
		# ccy=1-cg-cik*cky;
		# crkky=crk*cky;
		# cwhlc=(1/clandaw)*(1-calfa)/calfa*crk*cky/ccy;
		# cwly=1-crk*cky;
		# conster=(cr-1)*100;

% flexible economy

	      0*(1-calfa)*a + 1*a =  calfa*rkf+(1-calfa)*(wf)  ;
	      zcapf =  (1/(czcap/(1-czcap)))* rkf  ;
	      rkf =  (wf)+labf-kf ;
	      kf =  kpf(-1)+zcapf ;
	      invef = (1/(1+cbetabar*cgamma))* (  invef(-1) + cbetabar*cgamma*invef(1)+(1/(cgamma^2*csadjcost))*pkf ) +qs ;
          pkf = -rrf-0*b+(1/((1-chabb/cgamma)/(csigma*(1+chabb/cgamma))))*b +(crk/(crk+(1-ctou)))*rkf(1) +  ((1-ctou)/(crk+(1-ctou)))*pkf(1) ;
	      cf = (chabb/cgamma)/(1+chabb/cgamma)*cf(-1) + (1/(1+chabb/cgamma))*cf(+1) +((csigma-1)*cwhlc/(csigma*(1+chabb/cgamma)))*(labf-labf(+1)) - (1-chabb/cgamma)/(csigma*(1+chabb/cgamma))*(rrf+0*b) + b ;
	      yf = ccy*cf+ciy*invef+g  +  crkky*zcapf ;
	      yf = cfc*( calfa*kf+(1-calfa)*labf +a );
	      wf = csigl*labf 	+(1/(1-chabb/cgamma))*cf - (chabb/cgamma)/(1-chabb/cgamma)*cf(-1) ;
	      kpf =  (1-cikbar)*kpf(-1)+(cikbar)*invef + (cikbar)*(cgamma^2*csadjcost)*qs ;

% sticky price - wage economy

	      mc =  calfa*rk+(1-calfa)*(w) - 1*a - 0*(1-calfa)*a ;
	      zcap =  (1/(czcap/(1-czcap)))* rk ;
	      rk =  w+lab-k ;
	      k =  kp(-1)+zcap ;
	      inve = (1/(1+cbetabar*cgamma))* (  inve(-1) + cbetabar*cgamma*inve(1)+(1/(cgamma^2*csadjcost))*pk ) +qs ;
          pk = -r+pinf(1)-0*b +(1/((1-chabb/cgamma)/(csigma*(1+chabb/cgamma))))*b + (crk/(crk+(1-ctou)))*rk(1) +  ((1-ctou)/(crk+(1-ctou)))*pk(1) ;
	      c = (chabb/cgamma)/(1+chabb/cgamma)*c(-1) + (1/(1+chabb/cgamma))*c(+1) +((csigma-1)*cwhlc/(csigma*(1+chabb/cgamma)))*(lab-lab(+1)) - (1-chabb/cgamma)/(csigma*(1+chabb/cgamma))*(r-pinf(+1) + 0*b) +b ;
	      y = ccy*c+ciy*inve+g  +  1*crkky*zcap ;
	      y = cfc*( calfa*k+(1-calfa)*lab +a );
	      pinf =  (1/(1+cbetabar*cgamma*cindp)) * ( cbetabar*cgamma*pinf(1) +cindp*pinf(-1)
               +((1-cprobp)*(1-cbetabar*cgamma*cprobp)/cprobp)/((cfc-1)*curvp+1)*(mc)  )  + spinf ;
	      w =  (1/(1+cbetabar*cgamma))*w(-1)
               +(cbetabar*cgamma/(1+cbetabar*cgamma))*w(1)
               +(cindw/(1+cbetabar*cgamma))*pinf(-1)
               -(1+cbetabar*cgamma*cindw)/(1+cbetabar*cgamma)*pinf
               +(cbetabar*cgamma)/(1+cbetabar*cgamma)*pinf(1)
               +(1-cprobw)*(1-cbetabar*cgamma*cprobw)/((1+cbetabar*cgamma)*cprobw)*(1/((clandaw-1)*curvw+1))*
               (csigl*lab + (1/(1-chabb/cgamma))*c - ((chabb/cgamma)/(1-chabb/cgamma))*c(-1) -w)
               + 1*sw ;
%	      r =  crpi*(1-crr)*pinf +cry*(1-crr)*(y-yf)+crdy*(y-yf-y(-1)+yf(-1))+crr*r(-1)+ms  ;

% new variable created to re-introduce the monetary policy shock in optimal policy
% and avoid stochastic singularity under the estimation of the optimal policy model
		  dr=r-r(-1);
		  pinf_target=pinf+ms;

		  a = crhoa*a(-1)  + sig_a*ea;	%
	      b = crhob*b(-1) + sig_b*eb;
	      g = crhog*(g(-1)) + sig_g*eg + cgy*sig_a*ea;
	      qs = crhoqs*qs(-1) + sig_qs*eqs;
	      ms = crhoms*ms(-1) + sig_m*em;
	      spinf = crhopinf*spinf(-1) + epinfma - cmap*epinfma(-1);
	          epinfma=sig_pinf*epinf;
	      sw = crhow*sw(-1) + ewma - cmaw*ewma(-1) ;
	          ewma=sig_w*ew;
	      kp =  (1-cikbar)*kp(-1)+cikbar*inve + cikbar*cgamma^2*csadjcost*qs ;

% measurment equations

		dy=y-y(-1)+ctrend;
		dc=c-c(-1)+ctrend;
		dinve=inve-inve(-1)+ctrend;
		dw=w-w(-1)+ctrend;
		pinfobs = 1*(pinf) + constepinf;
		robs =    1*(r) + conster;
		labobs = lab + constelab;

observables dy dc dinve dw pinfobs robs labobs;

planner_objective{discount = 0.99,commitment=1-pelin_tp_1_2} -.5*(1*pinf_target^2+wy*y^2+wr*dr^2);

steady_state_model(imposed)
	dy=ctrend;
	dc=ctrend;
	dinve=ctrend;
	dw=ctrend;
	pinfobs=constepinf;
	robs = conster;
	labobs = constelab;

parameterization
	% fixed parameters
	crhoas,1; 	 % this parameter does not enter the model
	crhols,    0.9928;  % this parameter does not enter the model
	ctou,.025;
	clandaw,1.5;
	cg,0.18;
	curvp,10;
	curvw,10;

	% estimated parameters initialisation
	sig_a,   0.4618,0.01,2,inv_gamma_pdf(0.9);
	sig_b,   0.18185,0.01,2,inv_gamma_pdf(0.9);
	sig_g,   0.6090,0.01,2,inv_gamma_pdf(0.9);
	sig_qs,  0.46017,0.01,2,inv_gamma_pdf(0.9);
	sig_m,   0.2397,0.01,2,inv_gamma_pdf(0.9);
	sig_pinf,0.1455,0.01,2,inv_gamma_pdf(0.9);
	sig_w,   0.2089,0.01,2,inv_gamma_pdf(0.9);

	calfa,   .24, .2,.4,normal_pdf(.9);
	csigma,   1.5,.75,2.25,normal_pdf(0.9);
	cfc,      1.5, 1, 1.5,normal_pdf(.9);
	cgy,      0.51,.1,1.5,normal_pdf(.9);

	csadjcost, 6.0144,1,7,normal_pdf(0.9);
	chabb,     0.6361,0.3,0.7,beta_pdf(.9);
	cprobw,    0.8087,0.3,0.7,beta_pdf(.9);
	csigl,     1.9423,.5,3.5,normal_pdf(.9);
	cprobp,    0.6,0.3,0.7,beta_pdf(.9);
	cindw,     0.3243,0.3,0.7,beta_pdf(.9);
	cindp,     0.47,0.3,0.7,beta_pdf(.9);
	czcap,     0.2696,0.3,0.7,beta_pdf(.9);

%	% Taylor-rule monetary policy
%	crpi,      1.488,1,2,normal_pdf(.9);
%	crr,       0.8762,0.3,0.7,beta_pdf(.9);
%	cry,       0.0593,0.025,0.225,normal_pdf(.9);
%	crdy,      0.2347,0.025,0.225,normal_pdf(.9);

	% optimal policy
	wy, .6,.425,.825,gamma_pdf(.9);
	wr, .1,.2,.4,gamma_pdf(.9);

	crhoa,     0.9977,0.2,0.8,beta_pdf(.9);
	crhob,     0.5799,0.3,0.7,beta_pdf(.9);
	crhog,     0.9957,0.2,0.8,beta_pdf(.9);
	crhoqs,    0.7165,0.3,0.7,beta_pdf(.9);
	crhoms,    .3,0.3,0.7,beta_pdf(.9);
	crhopinf,  0.8,0.3,0.7,beta_pdf(.9);
	crhow,     0.8,0.3,0.7,beta_pdf(.9);
	cmap ,     0.7,0.3,0.7,beta_pdf(.9);
	cmaw  ,    0.7,0.3,0.7,beta_pdf(.9);

	% derived from steady state
	constebeta, 0.7420,.05,.8,gamma_pdf(.9);

	ctrend,     0.3982,.2,.6,normal_pdf(.9);
	constepinf, .7,.425,.825,gamma_pdf(.9);
	constelab,  1.2918,-4,4,normal_pdf(.9);

	pelin_tp_1_2,.1,0.3,0.7,beta_pdf(.9);
	pelin_tp_2_1,.1,0.3,0.7,beta_pdf(.9);

<commit_msg>update of a stochastic replanning example<commit_after>endogenous ewma epinfma  zcapf rkf kf pkf cf invef yf labf wf rrf mc zcap rk k pk c inve y lab pinf w r a
b g qs  ms  spinf sw kpf kp

endogenous labobs robs pinfobs dy dc dinve dw

endogenous dr pinf_target

exogenous ea eb eg  eqs  em  epinf ew

parameters curvw cgy curvp constelab constepinf constebeta cmaw cmap calfa
czcap csadjcost ctou csigma chabb cfc
cindw cprobw cindp cprobp csigl clandaw  crpi crdy cry crr
crhoa crhoas crhob crhog crhols crhoqs crhoms crhopinf crhow
ctrend cg, sig_a, sig_b,sig_w,sig_pinf,sig_m,sig_qs,sig_g

% loss function weights
parameters wy, wr

% we specify the probability of commitment (if it is to vary)
parameters gamma_prob

model(linear)

		# cpie=1+constepinf/100;
		# cgamma=1+ctrend/100 ;
		# cbeta=1/(1+constebeta/100);
		# clandap=cfc;
		# cbetabar=cbeta*cgamma^(-csigma);
		# cr=cpie/(cbeta*cgamma^(-csigma));
		# crk=(cbeta^(-1))*(cgamma^csigma) - (1-ctou);
		# cw = (calfa^calfa*(1-calfa)^(1-calfa)/(clandap*crk^calfa))^(1/(1-calfa));
		# cikbar=(1-(1-ctou)/cgamma);
		# cik=(1-(1-ctou)/cgamma)*cgamma;
		# clk=((1-calfa)/calfa)*(crk/cw);
		# cky=cfc*(clk)^(calfa-1);
		# ciy=cik*cky;
		# ccy=1-cg-cik*cky;
		# crkky=crk*cky;
		# cwhlc=(1/clandaw)*(1-calfa)/calfa*crk*cky/ccy;
		# cwly=1-crk*cky;
		# conster=(cr-1)*100;

% flexible economy

	      0*(1-calfa)*a + 1*a =  calfa*rkf+(1-calfa)*(wf)  ;
	      zcapf =  (1/(czcap/(1-czcap)))* rkf  ;
	      rkf =  (wf)+labf-kf ;
	      kf =  kpf(-1)+zcapf ;
	      invef = (1/(1+cbetabar*cgamma))* (  invef(-1) + cbetabar*cgamma*invef(1)+(1/(cgamma^2*csadjcost))*pkf ) +qs ;
          pkf = -rrf-0*b+(1/((1-chabb/cgamma)/(csigma*(1+chabb/cgamma))))*b +(crk/(crk+(1-ctou)))*rkf(1) +  ((1-ctou)/(crk+(1-ctou)))*pkf(1) ;
	      cf = (chabb/cgamma)/(1+chabb/cgamma)*cf(-1) + (1/(1+chabb/cgamma))*cf(+1) +((csigma-1)*cwhlc/(csigma*(1+chabb/cgamma)))*(labf-labf(+1)) - (1-chabb/cgamma)/(csigma*(1+chabb/cgamma))*(rrf+0*b) + b ;
	      yf = ccy*cf+ciy*invef+g  +  crkky*zcapf ;
	      yf = cfc*( calfa*kf+(1-calfa)*labf +a );
	      wf = csigl*labf 	+(1/(1-chabb/cgamma))*cf - (chabb/cgamma)/(1-chabb/cgamma)*cf(-1) ;
	      kpf =  (1-cikbar)*kpf(-1)+(cikbar)*invef + (cikbar)*(cgamma^2*csadjcost)*qs ;

% sticky price - wage economy

	      mc =  calfa*rk+(1-calfa)*(w) - 1*a - 0*(1-calfa)*a ;
	      zcap =  (1/(czcap/(1-czcap)))* rk ;
	      rk =  w+lab-k ;
	      k =  kp(-1)+zcap ;
	      inve = (1/(1+cbetabar*cgamma))* (  inve(-1) + cbetabar*cgamma*inve(1)+(1/(cgamma^2*csadjcost))*pk ) +qs ;
          pk = -r+pinf(1)-0*b +(1/((1-chabb/cgamma)/(csigma*(1+chabb/cgamma))))*b + (crk/(crk+(1-ctou)))*rk(1) +  ((1-ctou)/(crk+(1-ctou)))*pk(1) ;
	      c = (chabb/cgamma)/(1+chabb/cgamma)*c(-1) + (1/(1+chabb/cgamma))*c(+1) +((csigma-1)*cwhlc/(csigma*(1+chabb/cgamma)))*(lab-lab(+1)) - (1-chabb/cgamma)/(csigma*(1+chabb/cgamma))*(r-pinf(+1) + 0*b) +b ;
	      y = ccy*c+ciy*inve+g  +  1*crkky*zcap ;
	      y = cfc*( calfa*k+(1-calfa)*lab +a );
	      pinf =  (1/(1+cbetabar*cgamma*cindp)) * ( cbetabar*cgamma*pinf(1) +cindp*pinf(-1)
               +((1-cprobp)*(1-cbetabar*cgamma*cprobp)/cprobp)/((cfc-1)*curvp+1)*(mc)  )  + spinf ;
	      w =  (1/(1+cbetabar*cgamma))*w(-1)
               +(cbetabar*cgamma/(1+cbetabar*cgamma))*w(1)
               +(cindw/(1+cbetabar*cgamma))*pinf(-1)
               -(1+cbetabar*cgamma*cindw)/(1+cbetabar*cgamma)*pinf
               +(cbetabar*cgamma)/(1+cbetabar*cgamma)*pinf(1)
               +(1-cprobw)*(1-cbetabar*cgamma*cprobw)/((1+cbetabar*cgamma)*cprobw)*(1/((clandaw-1)*curvw+1))*
               (csigl*lab + (1/(1-chabb/cgamma))*c - ((chabb/cgamma)/(1-chabb/cgamma))*c(-1) -w)
               + 1*sw ;
%	      r =  crpi*(1-crr)*pinf +cry*(1-crr)*(y-yf)+crdy*(y-yf-y(-1)+yf(-1))+crr*r(-1)+ms  ;

% new variable created to re-introduce the monetary policy shock in optimal policy
% and avoid stochastic singularity under the estimation of the optimal policy model
		  dr=r-r(-1);
		  pinf_target=pinf+ms;

		  a = crhoa*a(-1)  + sig_a*ea;	%
	      b = crhob*b(-1) + sig_b*eb;
	      g = crhog*(g(-1)) + sig_g*eg + cgy*sig_a*ea;
	      qs = crhoqs*qs(-1) + sig_qs*eqs;
	      ms = crhoms*ms(-1) + sig_m*em;
	      spinf = crhopinf*spinf(-1) + epinfma - cmap*epinfma(-1);
	          epinfma=sig_pinf*epinf;
	      sw = crhow*sw(-1) + ewma - cmaw*ewma(-1) ;
	          ewma=sig_w*ew;
	      kp =  (1-cikbar)*kp(-1)+cikbar*inve + cikbar*cgamma^2*csadjcost*qs ;

% measurment equations

		dy=y-y(-1)+ctrend;
		dc=c-c(-1)+ctrend;
		dinve=inve-inve(-1)+ctrend;
		dw=w-w(-1)+ctrend;
		pinfobs = 1*(pinf) + constepinf;
		robs =    1*(r) + conster;
		labobs = lab + constelab;

observables dy dc dinve dw pinfobs robs labobs

planner_objective{discount = 0.99,commitment=gamma_prob} -.5*(1*pinf_target^2+wy*y^2+wr*dr^2);

steady_state_model(imposed)
	dy=ctrend;
	dc=ctrend;
	dinve=ctrend;
	dw=ctrend;
	pinfobs=constepinf;
	robs = conster;
	labobs = constelab;

parameterization
	% fixed parameters
	crhoas,1; 	 % this parameter does not enter the model
	crhols,    0.9928;  % this parameter does not enter the model
	ctou,.025;
	clandaw,1.5;
	cg,0.18;
	curvp,10;
	curvw,10;

	% estimated parameters initialisation
	sig_a,   0.4618,0.01,2,inv_gamma_pdf(0.9);
	sig_b,   0.18185,0.01,2,inv_gamma_pdf(0.9);
	sig_g,   0.6090,0.01,2,inv_gamma_pdf(0.9);
	sig_qs,  0.46017,0.01,2,inv_gamma_pdf(0.9);
	sig_m,   0.2397,0.01,2,inv_gamma_pdf(0.9);
	sig_pinf,0.1455,0.01,2,inv_gamma_pdf(0.9);
	sig_w,   0.2089,0.01,2,inv_gamma_pdf(0.9);

	calfa,   .24, .2,.4,normal_pdf(.9);
	csigma,   1.5,.75,2.25,normal_pdf(0.9);
	cfc,      1.5, 1, 1.5,normal_pdf(.9);
	cgy,      0.51,.1,1.5,normal_pdf(.9);

	csadjcost, 6.0144,1,7,normal_pdf(0.9);
	chabb,     0.6361,0.3,0.7,beta_pdf(.9);
	cprobw,    0.8087,0.3,0.7,beta_pdf(.9);
	csigl,     1.9423,.5,3.5,normal_pdf(.9);
	cprobp,    0.6,0.3,0.7,beta_pdf(.9);
	cindw,     0.3243,0.3,0.7,beta_pdf(.9);
	cindp,     0.47,0.3,0.7,beta_pdf(.9);
	czcap,     0.2696,0.3,0.7,beta_pdf(.9);

%	% Taylor-rule monetary policy
%	crpi,      1.488,1,2,normal_pdf(.9);
%	crr,       0.8762,0.3,0.7,beta_pdf(.9);
%	cry,       0.0593,0.025,0.225,normal_pdf(.9);
%	crdy,      0.2347,0.025,0.225,normal_pdf(.9);

	% optimal policy
	wy, .6,.425,.825,gamma_pdf(.9);
	wr, .1,.2,.4,gamma_pdf(.9);

	crhoa,     0.9977,0.2,0.8,beta_pdf(.9);
	crhob,     0.5799,0.3,0.7,beta_pdf(.9);
	crhog,     0.9957,0.2,0.8,beta_pdf(.9);
	crhoqs,    0.7165,0.3,0.7,beta_pdf(.9);
	crhoms,    .3,0.3,0.7,beta_pdf(.9);
	crhopinf,  0.8,0.3,0.7,beta_pdf(.9);
	crhow,     0.8,0.3,0.7,beta_pdf(.9);
	cmap ,     0.7,0.3,0.7,beta_pdf(.9);
	cmaw  ,    0.7,0.3,0.7,beta_pdf(.9);

	% derived from steady state
	constebeta, 0.7420,.05,.8,gamma_pdf(.9);

	ctrend,     0.3982,.2,.6,normal_pdf(.9);
	constepinf, .7,.425,.825,gamma_pdf(.9);
	constelab,  1.2918,-4,4,normal_pdf(.9);

	gamma_prob,.5,0.3,0.7,beta_pdf(.9);

<|endoftext|>


<commit_before>/// Figure 11.11 Using two mutexes
///
/// Findings:
/// - After wrestling with static mut again realized
///   that fh and hashlock are much better off stuffed into
///   a struct
///
/// Status: only partially implemented

extern crate libc;
use libc::{pthread_mutex_t, PTHREAD_MUTEX_INITIALIZER};
use libc::{pthread_mutex_init, pthread_mutex_lock};
use std::ptr::null;

const NHASH:usize = 29;
macro_rules! HASH {
    ($i:expr) => {{
        $i % NHASH as i64
    }}
}

struct Foo<'a> {
    f_count: i64,
    f_lock: pthread_mutex_t,
    f_id: i64,
    f_next: Option<Box<&'a Foo<'a>>>,
}

struct Hashmap<'a> {
    fh:Vec<Foo<'a>>,
    hashlock:pthread_mutex_t,
}

impl <'a>Hashmap<'a> {
    fn new() -> Hashmap<'a> {
        let mut fh = Vec::with_capacity(NHASH);
        for i in 0..NHASH {
            fh[i] = Foo {f_count: 1, f_lock: PTHREAD_MUTEX_INITIALIZER, f_id: -1, f_next: None};
        }
        Hashmap{fh:fh, hashlock: PTHREAD_MUTEX_INITIALIZER}
    }

    fn foo_alloc(&mut self, id: i64) -> Option<Foo> {
        // allocate the object
        unsafe {
            let mut foo = Foo { f_count: 1, f_lock: std::mem::zeroed(), f_id: id, f_next: None };
            if pthread_mutex_init(&mut foo.f_lock, null()) != 0 {
                // does not need free as foo is dropped upon return
                return None
            }
            let idx = HASH!(id);
            pthread_mutex_lock(&mut self.hashlock);
            foo.f_next = Some(Box::new(&self.fh[idx as usize]));
        }
        None
    }
}

fn main() {

}

<commit_msg>another commit ;-)<commit_after>/// Figure 11.11 Using two mutexes
///
/// Findings:
/// - After wrestling with static mut again realized
///   that fh and hashlock are much better off stuffed into
///   a struct
///
/// Status: only partially implemented

extern crate libc;
use libc::{pthread_mutex_t, PTHREAD_MUTEX_INITIALIZER};
use libc::{pthread_mutex_init, pthread_mutex_lock, pthread_mutex_unlock};
use std::ptr::null;
use std::collections::LinkedList;

const NHASH:usize = 29;
macro_rules! HASH {
    ($i:expr) => {{
        $i % NHASH as i64
    }}
}

struct Foo {
    f_count: i64,
    f_lock: pthread_mutex_t,
    f_id: i64,
}

struct Hashmap {
    fh:Vec<LinkedList<Foo>>,
    hashlock:pthread_mutex_t,
}

impl Hashmap {
    fn new() -> Hashmap {
        let mut fh = Vec::with_capacity(NHASH);
        for i in 0..NHASH {
            fh[i] = LinkedList::new();
        }
        Hashmap{fh:fh, hashlock: PTHREAD_MUTEX_INITIALIZER}
    }

    fn foo_alloc(&mut self, id: i64) -> Option<&Foo> {
        // allocate the object
        unsafe {
            let mut foo = Foo { f_count: 1, f_lock: std::mem::zeroed(), f_id: id};
            if pthread_mutex_init(&mut foo.f_lock, null()) != 0 {
                // does not need free as foo is dropped upon return
                return None
            }
            let idx = HASH!(id);
            pthread_mutex_lock(&mut self.hashlock);
            let mut ll = &mut self.fh[idx as usize];
            ll.push_back(foo);
            pthread_mutex_lock(&mut ll.front_mut().unwrap().f_lock);
            pthread_mutex_unlock(&mut self.hashlock);
            // continue initialization
            pthread_mutex_unlock(&mut ll.front_mut().unwrap().f_lock);
            Some(&foo)
        }
    }
}

fn main() {

}

<|endoftext|>


<commit_before>use std::io::Result as IoResult;
use std::path::PathBuf;

use toml::Value;

use fs2::FileExt;

use libimagstore::hook::Hook;
use libimagstore::hook::accessor::HookDataAccessor as HDA;
use libimagstore::hook::accessor::HookDataAccessorProvider;
use libimagstore::hook::accessor::StoreIdAccessor;
use libimagstore::hook::accessor::MutableHookDataAccessor;
use libimagstore::hook::accessor::NonMutableHookDataAccessor;
use libimagstore::hook::result::HookResult;
use libimagstore::hook::error::{HookError, HookErrorKind};
use libimagstore::storeid::StoreId;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Entry;

trait EntryFlock {
    fn lock(&self) -> IoResult<()>;
    fn unlock(&self) -> IoResult<()>;
}

impl EntryFlock for Entry {

    fn lock(&self) -> IoResult<()> {
        use std::fs::File;

        let location : PathBuf = self.get_location().clone().into();
        File::open(location).and_then(|file| file.lock_exclusive())
    }

    fn unlock(&self) -> IoResult<()> {
        use std::fs::File;

        let location : PathBuf = self.get_location().clone().into();
        File::open(location).and_then(|file| file.unlock())
    }

}

#[derive(PartialEq, Eq, Debug, Clone)]
pub enum Action {
    Lock,
    Unlock
}

fn action_to_str(a: &Action) -> &'static str {
    match *a {
        Action::Lock   => "lock",
        Action::Unlock => "unlock",
    }
}

#[derive(Debug, Clone)]
pub struct FlockUpdateHook {
    action: Action,
}

impl FlockUpdateHook {

    pub fn new(action: Action) -> FlockUpdateHook {
        FlockUpdateHook {
            action: action,
        }
    }

}

impl Hook for FlockUpdateHook {

    fn name(&self) -> &'static str {
        "stdhook_flock_update"
    }

    fn set_config(&mut self, _: &Value) {
        () // We are not configurable here.
    }

}

impl HookDataAccessorProvider for FlockUpdateHook {

    fn accessor(&self) -> HDA {
        HDA::StoreIdAccess(self)
    }

}

impl StoreIdAccessor for FlockUpdateHook {

    fn access(&self, id: &StoreId) -> HookResult<()> {
        debug!("[FLOCK HOOK][{}] {:?}", action_to_str(&self.action), id);
        Ok(())
    }

}

impl MutableHookDataAccessor for FlockUpdateHook {

    fn access_mut(&self, fle: &mut FileLockEntry) -> HookResult<()> {
        debug!("[FLOCK HOOK][{}] {:?}", action_to_str(&self.action), fle.get_location());
        fle.lock()
            .map_err(|e| HookError::new(HookErrorKind::HookExecutionError, Some(Box::new(e))))
            .map(|_| ())
    }

}

impl NonMutableHookDataAccessor for FlockUpdateHook {

    fn access(&self, fle: &FileLockEntry) -> HookResult<()> {
        debug!("[FLOCK HOOK][{}] {:?}", action_to_str(&self.action), fle.get_location());
        fle.unlock()
            .map_err(|e| HookError::new(HookErrorKind::HookExecutionError, Some(Box::new(e))))
            .map(|_| ())
    }

}

<commit_msg>Flock hook: Rewrite EntryFlock trait to return HookResult<commit_after>use toml::Value;

use fs2::FileExt;

use libimagstore::hook::Hook;
use libimagstore::hook::accessor::HookDataAccessor as HDA;
use libimagstore::hook::accessor::HookDataAccessorProvider;
use libimagstore::hook::accessor::StoreIdAccessor;
use libimagstore::hook::accessor::MutableHookDataAccessor;
use libimagstore::hook::accessor::NonMutableHookDataAccessor;
use libimagstore::hook::result::HookResult;
use libimagstore::hook::error::{HookError, HookErrorKind, MapErrInto};
use libimagstore::storeid::StoreId;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Entry;

trait EntryFlock {
    fn lock(&self) -> HookResult<()>;
    fn unlock(&self) -> HookResult<()>;
}

impl EntryFlock for Entry {

    fn lock(&self) -> HookResult<()> {
        use std::fs::File;

        self.get_location()
            .clone()
            .into_pathbuf()
            .map_err_into(HookErrorKind::HookExecutionError)
            .and_then(|loc| File::open(loc).map_err_into(HookErrorKind::HookExecutionError))
            .and_then(|file| file.lock_exclusive().map_err_into(HookErrorKind::HookExecutionError))
    }

    fn unlock(&self) -> HookResult<()> {
        use std::fs::File;

        self.get_location()
            .clone()
            .into_pathbuf()
            .map_err_into(HookErrorKind::HookExecutionError)
            .and_then(|loc| File::open(loc).map_err_into(HookErrorKind::HookExecutionError))
            .and_then(|file| file.unlock().map_err_into(HookErrorKind::HookExecutionError))
    }

}

#[derive(PartialEq, Eq, Debug, Clone)]
pub enum Action {
    Lock,
    Unlock
}

fn action_to_str(a: &Action) -> &'static str {
    match *a {
        Action::Lock   => "lock",
        Action::Unlock => "unlock",
    }
}

#[derive(Debug, Clone)]
pub struct FlockUpdateHook {
    action: Action,
}

impl FlockUpdateHook {

    pub fn new(action: Action) -> FlockUpdateHook {
        FlockUpdateHook {
            action: action,
        }
    }

}

impl Hook for FlockUpdateHook {

    fn name(&self) -> &'static str {
        "stdhook_flock_update"
    }

    fn set_config(&mut self, _: &Value) {
        () // We are not configurable here.
    }

}

impl HookDataAccessorProvider for FlockUpdateHook {

    fn accessor(&self) -> HDA {
        HDA::StoreIdAccess(self)
    }

}

impl StoreIdAccessor for FlockUpdateHook {

    fn access(&self, id: &StoreId) -> HookResult<()> {
        debug!("[FLOCK HOOK][{}] {:?}", action_to_str(&self.action), id);
        Ok(())
    }

}

impl MutableHookDataAccessor for FlockUpdateHook {

    fn access_mut(&self, fle: &mut FileLockEntry) -> HookResult<()> {
        debug!("[FLOCK HOOK][{}] {:?}", action_to_str(&self.action), fle.get_location());
        fle.lock()
            .map_err(|e| HookError::new(HookErrorKind::HookExecutionError, Some(Box::new(e))))
            .map(|_| ())
    }

}

impl NonMutableHookDataAccessor for FlockUpdateHook {

    fn access(&self, fle: &FileLockEntry) -> HookResult<()> {
        debug!("[FLOCK HOOK][{}] {:?}", action_to_str(&self.action), fle.get_location());
        fle.unlock()
            .map_err(|e| HookError::new(HookErrorKind::HookExecutionError, Some(Box::new(e))))
            .map(|_| ())
    }

}

<|endoftext|>


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

//! This module provides `Pruner` which manages a thread pruning old data in the background and is
//! meant to be triggered by other threads as they commit new data to the DB.

use crate::{
    schema::{
        jellyfish_merkle_node::JellyfishMerkleNodeSchema, stale_node_index::StaleNodeIndexSchema,
    },
    OP_COUNTER,
};
use failure::prelude::*;
use logger::prelude::*;
use schemadb::{ReadOptions, SchemaBatch, DB};
use std::{
    sync::{
        mpsc::{channel, Receiver, Sender},
        Arc, Mutex,
    },
    thread::JoinHandle,
};
use types::transaction::Version;

use failure::_core::sync::atomic::Ordering;
use std::sync::atomic::AtomicU64;
#[cfg(test)]
use std::thread::sleep;
#[cfg(test)]
use std::time::{Duration, Instant};

/// The `Pruner` is meant to be part of a `LibraDB` instance and runs in the background to prune old
/// data.
///
/// It creates a worker thread on construction and joins it on destruction. When destructed, it
/// quits the worker thread eagerly without waiting for all pending work to be done.
pub(crate) struct Pruner {
    /// Other than the latest version, how many historical versions to keep being readable. For
    /// example, this being 0 means keep only the latest version.
    num_historical_versions_to_keep: u64,
    /// The worker thread handle, created upon Pruner instance construction and joined upon its
    /// destruction. It only becomes `None` after joined in `drop()`.
    worker_thread: Option<JoinHandle<()>>,
    /// The sender side of the channel talking to the worker thread.
    command_sender: Mutex<Sender<Command>>,
    /// (For tests) A way for the worker thread to inform the `Pruner` the pruning progress. If it
    /// sets this atomic value to `V`, all versions before `V` can no longer be accessed.
    #[allow(dead_code)]
    worker_progress: Arc<AtomicU64>,
}

impl Pruner {
    /// Creates a worker thread that waits on a channel for pruning commands.
    pub fn new(db: Arc<DB>, num_historical_versions_to_keep: u64) -> Self {
        let (command_sender, command_receiver) = channel();
        let worker_progress = Arc::new(AtomicU64::new(0));
        let worker_progress_clone = Arc::clone(&worker_progress);

        let worker_thread = std::thread::Builder::new()
            .name("libradb_pruner".into())
            .spawn(move || Worker::new(db, command_receiver, worker_progress_clone).work_loop())
            .expect("Creating pruner thread should succeed.");

        Self {
            num_historical_versions_to_keep,
            worker_thread: Some(worker_thread),
            command_sender: Mutex::new(command_sender),
            worker_progress,
        }
    }

    /// Sends pruning command to the worker thread when necessary.
    pub fn wake(&self, latest_version: Version) {
        if latest_version > self.num_historical_versions_to_keep {
            let least_readable_version = latest_version - self.num_historical_versions_to_keep;
            self.command_sender
                .lock()
                .expect("command_sender to pruner thread should lock.")
                .send(Command::Prune {
                    least_readable_version,
                })
                .expect("Receiver should not destruct prematurely.");
        }
    }

    /// (For tests only.) Notifies the worker thread and waits for it to finish its job by polling
    /// an internal counter.
    #[cfg(test)]
    pub fn wake_and_wait(&self, latest_version: Version) -> Result<()> {
        self.wake(latest_version);

        if latest_version > self.num_historical_versions_to_keep {
            let least_readable_version = latest_version - self.num_historical_versions_to_keep;
            const TIMEOUT: Duration = Duration::from_millis(100);
            let end = Instant::now() + TIMEOUT;

            while Instant::now() < end {
                if self.worker_progress.load(Ordering::Relaxed) >= least_readable_version {
                    return Ok(());
                }
                sleep(Duration::from_millis(1));
            }
            bail!("Timeout waiting for pruner worker.");
        }
        Ok(())
    }
}

impl Drop for Pruner {
    fn drop(&mut self) {
        self.command_sender
            .lock()
            .expect("Locking command_sender should not fail.")
            .send(Command::Quit)
            .expect("Receiver should not destruct.");
        self.worker_thread
            .take()
            .expect("Worker thread must exist.")
            .join()
            .expect("Worker thread should join peacefully.");
    }
}

enum Command {
    Quit,
    Prune { least_readable_version: Version },
}

struct Worker {
    db: Arc<DB>,
    command_receiver: Receiver<Command>,
    least_readable_version: Version,
    /// (For tests) a way for the worker thread to inform the `Pruner` the pruning progress. If we
    /// set this atomic value to `V`, all versions before `V` can no longer be accessed.
    progress: Arc<AtomicU64>,
    /// indicates if there's NOT any pending work to do currently, to hint
    /// `Self::receive_commands()` to `recv()` blocking-ly.
    blocking_recv: bool,
}

impl Worker {
    const BATCH_SIZE: usize = 1024;

    fn new(db: Arc<DB>, command_receiver: Receiver<Command>, progress: Arc<AtomicU64>) -> Self {
        Self {
            db,
            command_receiver,
            progress,
            least_readable_version: 0,
            blocking_recv: true,
        }
    }

    fn work_loop(mut self) {
        while self.receive_commands() {
            // Process a reasonably small batch of work before trying to receive commands again,
            // in case `Command::Quit` is received (that's when we should quit.)
            match prune_state(
                Arc::clone(&self.db),
                self.progress.load(Ordering::Relaxed),
                self.least_readable_version,
                Self::BATCH_SIZE,
            ) {
                Ok((num_pruned, last_seen_version)) => {
                    // Make next recv() blocking if all done.
                    self.blocking_recv = num_pruned < Self::BATCH_SIZE;

                    // Log the progress.
                    self.progress.store(last_seen_version, Ordering::Relaxed);
                    OP_COUNTER.set(
                        "pruner.least_readable_state_version",
                        last_seen_version as usize,
                    );
                }
                Err(e) => {
                    crit!("Error purging db records. {:?}", e);
                    // On error, stop retrying vigorously by making next recv() blocking.
                    self.blocking_recv = true;
                }
            }
        }
    }

    /// Tries to receive all pending commands, blocking waits for the next command if no work needs
    /// to be done, otherwise quits with `true` to allow the outer loop to do some work before
    /// getting back here.
    ///
    /// Returns `false` if `Command::Quit` is received, to break the outer loop and let
    /// `work_loop()` return.
    fn receive_commands(&mut self) -> bool {
        loop {
            let command = if self.blocking_recv {
                // Worker has nothing to do, blocking wait for the next command.
                self.command_receiver
                    .recv()
                    .expect("Sender should not destruct prematurely.")
            } else {
                // Worker has pending work to do, non-blocking recv.
                match self.command_receiver.try_recv() {
                    Ok(command) => command,
                    // Channel has drained, yield control to the outer loop.
                    Err(_) => return true,
                }
            };

            match command {
                // On `Command::Quit` inform the outer loop to quit by returning `false`.
                Command::Quit => return false,
                Command::Prune {
                    least_readable_version,
                } => {
                    if least_readable_version > self.least_readable_version {
                        self.least_readable_version = least_readable_version;
                        // Switch to non-blocking to allow some work to be done after the
                        // channel has drained.
                        self.blocking_recv = false;
                    }
                }
            }
        }
    }
}

pub fn prune_state(
    db: Arc<DB>,
    // `iter.seek_to_first()` can be costly if there are a lot of deletes at the beginning of the
    // whole key range which have not been compacted away yet. We let the call site hint us where
    // the first undeleted key is if possible. Pass in `0` to essentially seek to the first record.
    max_pruned_version_hint: Version,
    least_readable_version: Version,
    limit: usize,
) -> Result<(usize, Version)> {
    let mut batch = SchemaBatch::new();
    let mut num_pruned = 0;
    let mut iter = db.iter::<StaleNodeIndexSchema>(ReadOptions::default())?;
    iter.seek(&max_pruned_version_hint)?;

    // Collect records to prune, as many as `limit`.
    let mut iter = iter.take(limit);
    let mut last_seen_version = 0;
    while let Some((index, _)) = iter.next().transpose()? {
        // Only records that have retired before or at version `least_readable_version` can be
        // pruned in order to keep that version still readable after pruning.
        if index.stale_since_version > least_readable_version {
            break;
        }
        last_seen_version = index.stale_since_version;
        batch.delete::<JellyfishMerkleNodeSchema>(&index.node_key)?;
        batch.delete::<StaleNodeIndexSchema>(&index)?;
        num_pruned += 1;
    }

    // Persist.
    if num_pruned > 0 {
        db.write_schemas(batch)?;
    }

    Ok((num_pruned, last_seen_version))
}

#[cfg(test)]
mod test;
<commit_msg>[storage] trivial: enlarges timeout in `Pruner::wake_and_wait()` (tests only)<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

//! This module provides `Pruner` which manages a thread pruning old data in the background and is
//! meant to be triggered by other threads as they commit new data to the DB.

use crate::{
    schema::{
        jellyfish_merkle_node::JellyfishMerkleNodeSchema, stale_node_index::StaleNodeIndexSchema,
    },
    OP_COUNTER,
};
use failure::prelude::*;
use logger::prelude::*;
use schemadb::{ReadOptions, SchemaBatch, DB};
use std::{
    sync::{
        mpsc::{channel, Receiver, Sender},
        Arc, Mutex,
    },
    thread::JoinHandle,
};
use types::transaction::Version;

use failure::_core::sync::atomic::Ordering;
use std::sync::atomic::AtomicU64;
#[cfg(test)]
use std::thread::sleep;
#[cfg(test)]
use std::time::{Duration, Instant};

/// The `Pruner` is meant to be part of a `LibraDB` instance and runs in the background to prune old
/// data.
///
/// It creates a worker thread on construction and joins it on destruction. When destructed, it
/// quits the worker thread eagerly without waiting for all pending work to be done.
pub(crate) struct Pruner {
    /// Other than the latest version, how many historical versions to keep being readable. For
    /// example, this being 0 means keep only the latest version.
    num_historical_versions_to_keep: u64,
    /// The worker thread handle, created upon Pruner instance construction and joined upon its
    /// destruction. It only becomes `None` after joined in `drop()`.
    worker_thread: Option<JoinHandle<()>>,
    /// The sender side of the channel talking to the worker thread.
    command_sender: Mutex<Sender<Command>>,
    /// (For tests) A way for the worker thread to inform the `Pruner` the pruning progress. If it
    /// sets this atomic value to `V`, all versions before `V` can no longer be accessed.
    #[allow(dead_code)]
    worker_progress: Arc<AtomicU64>,
}

impl Pruner {
    /// Creates a worker thread that waits on a channel for pruning commands.
    pub fn new(db: Arc<DB>, num_historical_versions_to_keep: u64) -> Self {
        let (command_sender, command_receiver) = channel();
        let worker_progress = Arc::new(AtomicU64::new(0));
        let worker_progress_clone = Arc::clone(&worker_progress);

        let worker_thread = std::thread::Builder::new()
            .name("libradb_pruner".into())
            .spawn(move || Worker::new(db, command_receiver, worker_progress_clone).work_loop())
            .expect("Creating pruner thread should succeed.");

        Self {
            num_historical_versions_to_keep,
            worker_thread: Some(worker_thread),
            command_sender: Mutex::new(command_sender),
            worker_progress,
        }
    }

    /// Sends pruning command to the worker thread when necessary.
    pub fn wake(&self, latest_version: Version) {
        if latest_version > self.num_historical_versions_to_keep {
            let least_readable_version = latest_version - self.num_historical_versions_to_keep;
            self.command_sender
                .lock()
                .expect("command_sender to pruner thread should lock.")
                .send(Command::Prune {
                    least_readable_version,
                })
                .expect("Receiver should not destruct prematurely.");
        }
    }

    /// (For tests only.) Notifies the worker thread and waits for it to finish its job by polling
    /// an internal counter.
    #[cfg(test)]
    pub fn wake_and_wait(&self, latest_version: Version) -> Result<()> {
        self.wake(latest_version);

        if latest_version > self.num_historical_versions_to_keep {
            let least_readable_version = latest_version - self.num_historical_versions_to_keep;
            // Assuming no big pruning chunks will be issued by a test.
            const TIMEOUT: Duration = Duration::from_secs(10);
            let end = Instant::now() + TIMEOUT;

            while Instant::now() < end {
                if self.worker_progress.load(Ordering::Relaxed) >= least_readable_version {
                    return Ok(());
                }
                sleep(Duration::from_millis(1));
            }
            bail!("Timeout waiting for pruner worker.");
        }
        Ok(())
    }
}

impl Drop for Pruner {
    fn drop(&mut self) {
        self.command_sender
            .lock()
            .expect("Locking command_sender should not fail.")
            .send(Command::Quit)
            .expect("Receiver should not destruct.");
        self.worker_thread
            .take()
            .expect("Worker thread must exist.")
            .join()
            .expect("Worker thread should join peacefully.");
    }
}

enum Command {
    Quit,
    Prune { least_readable_version: Version },
}

struct Worker {
    db: Arc<DB>,
    command_receiver: Receiver<Command>,
    least_readable_version: Version,
    /// (For tests) a way for the worker thread to inform the `Pruner` the pruning progress. If we
    /// set this atomic value to `V`, all versions before `V` can no longer be accessed.
    progress: Arc<AtomicU64>,
    /// indicates if there's NOT any pending work to do currently, to hint
    /// `Self::receive_commands()` to `recv()` blocking-ly.
    blocking_recv: bool,
}

impl Worker {
    const BATCH_SIZE: usize = 1024;

    fn new(db: Arc<DB>, command_receiver: Receiver<Command>, progress: Arc<AtomicU64>) -> Self {
        Self {
            db,
            command_receiver,
            progress,
            least_readable_version: 0,
            blocking_recv: true,
        }
    }

    fn work_loop(mut self) {
        while self.receive_commands() {
            // Process a reasonably small batch of work before trying to receive commands again,
            // in case `Command::Quit` is received (that's when we should quit.)
            match prune_state(
                Arc::clone(&self.db),
                self.progress.load(Ordering::Relaxed),
                self.least_readable_version,
                Self::BATCH_SIZE,
            ) {
                Ok((num_pruned, last_seen_version)) => {
                    // Make next recv() blocking if all done.
                    self.blocking_recv = num_pruned < Self::BATCH_SIZE;

                    // Log the progress.
                    self.progress.store(last_seen_version, Ordering::Relaxed);
                    OP_COUNTER.set(
                        "pruner.least_readable_state_version",
                        last_seen_version as usize,
                    );
                }
                Err(e) => {
                    crit!("Error purging db records. {:?}", e);
                    // On error, stop retrying vigorously by making next recv() blocking.
                    self.blocking_recv = true;
                }
            }
        }
    }

    /// Tries to receive all pending commands, blocking waits for the next command if no work needs
    /// to be done, otherwise quits with `true` to allow the outer loop to do some work before
    /// getting back here.
    ///
    /// Returns `false` if `Command::Quit` is received, to break the outer loop and let
    /// `work_loop()` return.
    fn receive_commands(&mut self) -> bool {
        loop {
            let command = if self.blocking_recv {
                // Worker has nothing to do, blocking wait for the next command.
                self.command_receiver
                    .recv()
                    .expect("Sender should not destruct prematurely.")
            } else {
                // Worker has pending work to do, non-blocking recv.
                match self.command_receiver.try_recv() {
                    Ok(command) => command,
                    // Channel has drained, yield control to the outer loop.
                    Err(_) => return true,
                }
            };

            match command {
                // On `Command::Quit` inform the outer loop to quit by returning `false`.
                Command::Quit => return false,
                Command::Prune {
                    least_readable_version,
                } => {
                    if least_readable_version > self.least_readable_version {
                        self.least_readable_version = least_readable_version;
                        // Switch to non-blocking to allow some work to be done after the
                        // channel has drained.
                        self.blocking_recv = false;
                    }
                }
            }
        }
    }
}

pub fn prune_state(
    db: Arc<DB>,
    // `iter.seek_to_first()` can be costly if there are a lot of deletes at the beginning of the
    // whole key range which have not been compacted away yet. We let the call site hint us where
    // the first undeleted key is if possible. Pass in `0` to essentially seek to the first record.
    max_pruned_version_hint: Version,
    least_readable_version: Version,
    limit: usize,
) -> Result<(usize, Version)> {
    let mut batch = SchemaBatch::new();
    let mut num_pruned = 0;
    let mut iter = db.iter::<StaleNodeIndexSchema>(ReadOptions::default())?;
    iter.seek(&max_pruned_version_hint)?;

    // Collect records to prune, as many as `limit`.
    let mut iter = iter.take(limit);
    let mut last_seen_version = 0;
    while let Some((index, _)) = iter.next().transpose()? {
        // Only records that have retired before or at version `least_readable_version` can be
        // pruned in order to keep that version still readable after pruning.
        if index.stale_since_version > least_readable_version {
            break;
        }
        last_seen_version = index.stale_since_version;
        batch.delete::<JellyfishMerkleNodeSchema>(&index.node_key)?;
        batch.delete::<StaleNodeIndexSchema>(&index)?;
        num_pruned += 1;
    }

    // Persist.
    if num_pruned > 0 {
        db.write_schemas(batch)?;
    }

    Ok((num_pruned, last_seen_version))
}

#[cfg(test)]
mod test;
<|endoftext|>


<commit_before>#![allow(clippy::type_complexity)]

use intercom::prelude::*;
use intercom::type_system::{ExternType, ExternOutput, TypeSystem};
use intercom::IUnknown;
use std::ffi::c_void;

#[com_class(IOutputMemoryTests)]
#[derive(Default)]
pub struct OutputMemoryTests;

#[com_interface]
pub trait IOutputMemoryTests
{
    fn succeed(
        &self,
        input: &ComItf<dyn IUnknown>,
    ) -> ComResult<(ComRc<dyn IUnknown>, ComRc<dyn IUnknown>)>;

    fn fail(
        &self,
        input: &ComItf<dyn IUnknown>,
    ) -> ComResult<(ComRc<dyn IUnknown>, FailingType, ComRc<dyn IUnknown>)>;

    fn call_succeed(
        &self,
        itf: &ComItf<dyn IOutputMemoryTests>,
        input: &ComItf<dyn IUnknown>,
    ) -> ComResult<()>;

    fn call_fail(
        &self,
        itf: &ComItf<dyn IOutputMemoryTests>,
        input: &ComItf<dyn IUnknown>,
    ) -> ComResult<()>;
}

impl IOutputMemoryTests for OutputMemoryTests
{
    fn succeed(
        &self,
        input: &ComItf<dyn IUnknown>,
    ) -> ComResult<(ComRc<dyn IUnknown>, ComRc<dyn IUnknown>)>
    {
        Ok((input.into(), input.into()))
    }

    fn fail(
        &self,
        input: &ComItf<dyn IUnknown>,
    ) -> ComResult<(ComRc<dyn IUnknown>, FailingType, ComRc<dyn IUnknown>)>
    {
        Ok((input.into(), FailingType, input.into()))
    }

    fn call_succeed(
        &self,
        itf: &ComItf<dyn IOutputMemoryTests>,
        input: &ComItf<dyn IUnknown>,
    ) -> ComResult<()>
    {
        itf.succeed(input).map(|_| ())
    }

    fn call_fail(
        &self,
        itf: &ComItf<dyn IOutputMemoryTests>,
        input: &ComItf<dyn IUnknown>,
    ) -> ComResult<()>
    {
        itf.fail(input).map(|_| ())
    }
}

/// A type that fails all conversions.
pub struct FailingType;
unsafe impl<TS: TypeSystem> ExternType<TS> for FailingType
{
    type ForeignType = *mut c_void;
}

unsafe impl<TS: TypeSystem> ExternOutput<TS> for FailingType
{
    fn into_foreign_output(self) -> ComResult<Self::ForeignType>
    {
        Err(ComError::E_FAIL)
    }

    unsafe fn from_foreign_output(_: Self::ForeignType) -> ComResult<Self>
    {
        Err(ComError::E_FAIL)
    }
}
<commit_msg>Fix style<commit_after>#![allow(clippy::type_complexity)]

use intercom::prelude::*;
use intercom::type_system::{ExternOutput, ExternType, TypeSystem};
use intercom::IUnknown;
use std::ffi::c_void;

#[com_class(IOutputMemoryTests)]
#[derive(Default)]
pub struct OutputMemoryTests;

#[com_interface]
pub trait IOutputMemoryTests
{
    fn succeed(
        &self,
        input: &ComItf<dyn IUnknown>,
    ) -> ComResult<(ComRc<dyn IUnknown>, ComRc<dyn IUnknown>)>;

    fn fail(
        &self,
        input: &ComItf<dyn IUnknown>,
    ) -> ComResult<(ComRc<dyn IUnknown>, FailingType, ComRc<dyn IUnknown>)>;

    fn call_succeed(
        &self,
        itf: &ComItf<dyn IOutputMemoryTests>,
        input: &ComItf<dyn IUnknown>,
    ) -> ComResult<()>;

    fn call_fail(
        &self,
        itf: &ComItf<dyn IOutputMemoryTests>,
        input: &ComItf<dyn IUnknown>,
    ) -> ComResult<()>;
}

impl IOutputMemoryTests for OutputMemoryTests
{
    fn succeed(
        &self,
        input: &ComItf<dyn IUnknown>,
    ) -> ComResult<(ComRc<dyn IUnknown>, ComRc<dyn IUnknown>)>
    {
        Ok((input.into(), input.into()))
    }

    fn fail(
        &self,
        input: &ComItf<dyn IUnknown>,
    ) -> ComResult<(ComRc<dyn IUnknown>, FailingType, ComRc<dyn IUnknown>)>
    {
        Ok((input.into(), FailingType, input.into()))
    }

    fn call_succeed(
        &self,
        itf: &ComItf<dyn IOutputMemoryTests>,
        input: &ComItf<dyn IUnknown>,
    ) -> ComResult<()>
    {
        itf.succeed(input).map(|_| ())
    }

    fn call_fail(
        &self,
        itf: &ComItf<dyn IOutputMemoryTests>,
        input: &ComItf<dyn IUnknown>,
    ) -> ComResult<()>
    {
        itf.fail(input).map(|_| ())
    }
}

/// A type that fails all conversions.
pub struct FailingType;
unsafe impl<TS: TypeSystem> ExternType<TS> for FailingType
{
    type ForeignType = *mut c_void;
}

unsafe impl<TS: TypeSystem> ExternOutput<TS> for FailingType
{
    fn into_foreign_output(self) -> ComResult<Self::ForeignType>
    {
        Err(ComError::E_FAIL)
    }

    unsafe fn from_foreign_output(_: Self::ForeignType) -> ComResult<Self>
    {
        Err(ComError::E_FAIL)
    }
}
<|endoftext|>