<commit_before>//! Utilies for running in a build script.

use grammar::parse_tree as pt;
use grammar::repr as r;
use lalrpop_util::ParseError;
use lexer::intern_token;
use lr1;
use normalize;
use parser;
use rust::RustWrite;
use tok;
use self::filetext::FileText;

use std::env::current_dir;
use std::fs;
use std::io::{self, Write};
use std::path::{Path, PathBuf};
use std::process::exit;

mod action;
mod filetext;

pub fn process_root() -> io::Result<()> {
    process_dir(try!(current_dir()), false)
}

pub fn process_root_unconditionally() -> io::Result<()> {
    process_dir(try!(current_dir()), true)
}

fn process_dir<P:AsRef<Path>>(root_dir: P, force_build: bool) -> io::Result<()> {
    let lalrpop_files = try!(lalrpop_files(root_dir));
    for lalrpop_file in lalrpop_files {
        let rs_file = lalrpop_file.with_extension("rs");
        if force_build || try!(needs_rebuild(&lalrpop_file, &rs_file)) {
            try!(make_read_only(&rs_file, false));
            try!(remove_old_file(&rs_file));
            let grammar = try!(parse_and_normalize_grammar(lalrpop_file));
            try!(emit_recursive_ascent(&rs_file, &grammar));
            try!(make_read_only(&rs_file, true));
        }
    }
    Ok(())
}

fn remove_old_file(rs_file: &Path) -> io::Result<()> {
    match fs::remove_file(rs_file) {
        Ok(()) => Ok(()),
        Err(e) => {
            // Unix reports NotFound, Windows PermissionDenied!
            match e.kind() {
                io::ErrorKind::NotFound | io::ErrorKind::PermissionDenied=> Ok(()),
                _ => Err(e),
            }
        }
    }
}

fn needs_rebuild(lalrpop_file: &Path,
                 rs_file: &Path)
                 -> io::Result<bool>
{
    return match fs::metadata(&rs_file) {
        Ok(rs_metadata) => {
            let lalrpop_metadata = try!(fs::metadata(&lalrpop_file));
            Ok(compare_modification_times(&lalrpop_metadata, &rs_metadata))
        }
        Err(e) => {
            match e.kind() {
                io::ErrorKind::NotFound => Ok(true),
                _ => Err(e),
            }
        }
    };

    #[cfg(unix)]
    fn compare_modification_times(lalrpop_metadata: &fs::Metadata,
                                  rs_metadata: &fs::Metadata)
                                  -> bool
    {
        use std::os::unix::fs::MetadataExt;
        lalrpop_metadata.mtime() >= rs_metadata.mtime()
    }

    #[cfg(windows)]
    fn compare_modification_times(lalrpop_metadata: &fs::Metadata,
                                  rs_metadata: &fs::Metadata)
                                  -> bool
    {
        use std::os::windows::fs::MetadataExt;
        lalrpop_metadata.last_write_time() >= rs_metadata.last_write_time()
    }

    #[cfg(not(any(unix,windows)))]
    fn compare_modification_times(lalrpop_metadata: &fs::Metadata,
                                  rs_metadata: &fs::Metadata)
                                  -> bool
    {
        true
    }
}

fn make_read_only(rs_file: &Path, ro: bool) -> io::Result<()> {
    let rs_metadata = try!(fs::metadata(&rs_file));
    let mut rs_permissions = rs_metadata.permissions();
    rs_permissions.set_readonly(ro);
    fs::set_permissions(&rs_file, rs_permissions)
}

fn lalrpop_files<P:AsRef<Path>>(root_dir: P) -> io::Result<Vec<PathBuf>> {
    let mut result = vec![];
    for entry in try!(fs::read_dir(root_dir)) {
        let entry = try!(entry);
        let file_type = try!(entry.file_type());

        let path = entry.path();

        if file_type.is_dir() {
            result.extend(try!(lalrpop_files(&path)));
        }

        if
            file_type.is_file() &&
            path.extension().is_some() &&
            path.extension().unwrap() == "lalrpop"
        {
            result.push(path);
        }
    }
    Ok(result)
}

fn parse_and_normalize_grammar(path: PathBuf) -> io::Result<r::Grammar> {
    let input = try!(FileText::from_path(path));

    let grammar = match parser::parse_grammar(input.text()) {
        Ok(grammar) => grammar,

        Err(ParseError::InvalidToken { location }) => {
            let ch = input.text()[location..].chars().next().unwrap();
            report_error(&input,
                         pt::Span(location, location),
                         &format!("invalid character `{}`", ch));
        }

        Err(ParseError::UnrecognizedToken { token: None, expected: _ }) => {
            let len = input.text().len();
            report_error(&input,
                         pt::Span(len, len),
                         &format!("unexpected end of file"));
        }

        Err(ParseError::UnrecognizedToken { token: Some((lo, _, hi)), expected }) => {
            assert!(expected.is_empty()); // didn't implement this yet :)
            let text = &input.text()[lo..hi];
            report_error(&input,
                         pt::Span(lo, hi),
                         &format!("unexpected token: `{}`", text));
        }

        Err(ParseError::ExtraToken { token: (lo, _, hi) }) => {
            let text = &input.text()[lo..hi];
            report_error(&input,
                         pt::Span(lo, hi),
                         &format!("extra token at end of input: `{}`", text));
        }

        Err(ParseError::User { error }) => {
            let string = match error.code {
                tok::ErrorCode::UnrecognizedToken =>
                    "unrecognized token",
                tok::ErrorCode::UnterminatedEscape =>
                    "unterminated escape; missing '`'?",
                tok::ErrorCode::UnterminatedStringLiteral =>
                    "unterminated string literal; missing `\"`?",
                tok::ErrorCode::ExpectedStringLiteral =>
                    "expected string literal; missing `\"`?",
                tok::ErrorCode::UnterminatedCode =>
                    "unterminated code block; perhaps a missing `;`, `)`, `]` or `}`?"
            };

            report_error(&input,
                         pt::Span(error.location, error.location + 1),
                         string)
        }
    };

    match normalize::normalize(grammar) {
        Ok(grammar) => Ok(grammar),
        Err(error) => {
            report_error(&input,
                         error.span,
                         &error.message)
        }
    }
}

fn report_error(file_text: &FileText, span: pt::Span, message: &str) -> ! {
    println!("{} error: {}", file_text.span_str(span), message);

    let out = io::stdout();
    let mut out = out.lock();
    file_text.highlight(span, &mut out).unwrap();

    exit(1);
}

fn emit_uses<W:Write>(grammar: &r::Grammar,
                      rust: &mut RustWrite<W>)
                      -> io::Result<()>
{
    rust.write_uses("", grammar)
}

fn emit_recursive_ascent(output_path: &Path, grammar: &r::Grammar) -> io::Result<()>
{
    let output_file = try!(fs::File::create(output_path));
    let mut rust = RustWrite::new(output_file);

    // We generate a module structure like this:
    //
    // ```
    // mod <output-file> {
    //     // For each public symbol:
    //     pub fn parse_XYZ();
    //     mod __XYZ { ... }
    //
    //     // For each bit of action code:
    //     <action-code>
    // }
    // ```
    //
    // Note that the action code goes in the outer module.  This is
    // intentional because it means that the foo.lalrpop file serves
    // as a module in the rust hierarchy, so if the action code
    // includes things like `super::` it will resolve in the natural
    // way.

    // often some of the uses are not used here
    rust!(rust, "#![allow(unused_imports)]");

    // we always thread the parameters through to the action code,
    // even if they are not used, and hence we need to disable the
    // unused variables lint, which otherwise gets very excited.
    if !grammar.parameters.is_empty() {
        rust!(rust, "#![allow(unused_variables)]");
    }

    try!(emit_uses(grammar, &mut rust));

    if grammar.start_nonterminals.is_empty() {
        println!("Error: no public symbols declared in grammar");
        exit(1);
    }

    for (&user_nt, &start_nt) in &grammar.start_nonterminals {
        // We generate these, so there should always be exactly 1
        // production. Otherwise the LR(1) algorithm doesn't know
        // where to stop!
        assert_eq!(grammar.productions_for(start_nt).len(), 1);

        let states = match lr1::build_states(&grammar, start_nt) {
            Ok(states) => states,
            Err(error) => {
                try!(lr1::report_error(&mut io::stdout(), &grammar, &error));
                exit(1)
            }
        };

        try!(lr1::ascent::compile(&grammar, user_nt, start_nt, &states, &mut rust));

        rust!(rust, "pub use self::{}parse{}::parse_{};",
              grammar.prefix, start_nt, user_nt);
    }

    if let Some(ref intern_token) = grammar.intern_token {
        try!(intern_token::compile(&grammar, intern_token, &mut rust));
    }

    try!(action::emit_action_code(grammar, &mut rust));

    try!(emit_to_triple_trait(grammar, &mut rust));

    Ok(())
}

fn emit_to_triple_trait<W:Write>(grammar: &r::Grammar,
                                 rust: &mut RustWrite<W>)
                                 -> io::Result<()>
{
    #![allow(non_snake_case)]

    let L = grammar.types.terminal_loc_type();
    let T = grammar.types.terminal_token_type();
    let E = grammar.types.error_type();

    let mut user_type_parameters = String::new();
    for type_parameter in &grammar.type_parameters {
        user_type_parameters.push_str(&format!("{}, ", type_parameter));
    }

    rust!(rust, "");
    rust!(rust, "pub trait {}ToTriple<{}> {{", grammar.prefix, user_type_parameters);
    rust!(rust, "type Error;");
    rust!(rust, "fn to_triple(value: Self) -> Result<({},{},{}),Self::Error>;", L, T, L);
    rust!(rust, "}}");

    rust!(rust, "");
    if grammar.types.opt_terminal_loc_type().is_some() {
        rust!(rust, "impl<{}> {}ToTriple<{}> for ({}, {}, {}) {{",
              user_type_parameters, grammar.prefix, user_type_parameters, L, T, L);
        rust!(rust, "type Error = {};", E);
        rust!(rust, "fn to_triple(value: Self) -> Result<({},{},{}),{}> {{", L, T, L, E);
        rust!(rust, "Ok(value)");
        rust!(rust, "}}");
        rust!(rust, "}}");

        rust!(rust, "impl<{}> {}ToTriple<{}> for Result<({}, {}, {}),{}> {{",
              user_type_parameters, grammar.prefix, user_type_parameters, L, T, L, E);
        rust!(rust, "type Error = {};", E);
        rust!(rust, "fn to_triple(value: Self) -> Result<({},{},{}),{}> {{", L, T, L, E);
        rust!(rust, "value");
        rust!(rust, "}}");
        rust!(rust, "}}");
    } else {
        rust!(rust, "impl<{}> {}ToTriple<{}> for {} {{",
              user_type_parameters, grammar.prefix, user_type_parameters, T);
        rust!(rust, "type Error = {};", E);
        rust!(rust, "fn to_triple(value: Self) -> Result<((),{},()),{}> {{", T, E);
        rust!(rust, "Ok(((), value, ()))");
        rust!(rust, "}}");
        rust!(rust, "}}");

        rust!(rust, "impl<{}> {}ToTriple<{}> for Result<({}),{}> {{",
              user_type_parameters, grammar.prefix, user_type_parameters, T, E);
        rust!(rust, "type Error = {};", E);
        rust!(rust, "fn to_triple(value: Self) -> Result<((),{},()),{}> {{", T, E);
        rust!(rust, "value.map(|v| ((), v, ()))");
        rust!(rust, "}}");
        rust!(rust, "}}");
    }

    Ok(())
}
<commit_msg>Verify that generated rust file exists before changing permissions.<commit_after>//! Utilies for running in a build script.

use grammar::parse_tree as pt;
use grammar::repr as r;
use lalrpop_util::ParseError;
use lexer::intern_token;
use lr1;
use normalize;
use parser;
use rust::RustWrite;
use tok;
use self::filetext::FileText;

use std::env::current_dir;
use std::fs;
use std::io::{self, Write};
use std::path::{Path, PathBuf};
use std::process::exit;

mod action;
mod filetext;

pub fn process_root() -> io::Result<()> {
    process_dir(try!(current_dir()), false)
}

pub fn process_root_unconditionally() -> io::Result<()> {
    process_dir(try!(current_dir()), true)
}

fn process_dir<P:AsRef<Path>>(root_dir: P, force_build: bool) -> io::Result<()> {
    let lalrpop_files = try!(lalrpop_files(root_dir));
    for lalrpop_file in lalrpop_files {
        let rs_file = lalrpop_file.with_extension("rs");
        if force_build || try!(needs_rebuild(&lalrpop_file, &rs_file)) {
            try!(make_read_only(&rs_file, false));
            try!(remove_old_file(&rs_file));
            let grammar = try!(parse_and_normalize_grammar(lalrpop_file));
            try!(emit_recursive_ascent(&rs_file, &grammar));
            try!(make_read_only(&rs_file, true));
        }
    }
    Ok(())
}

fn remove_old_file(rs_file: &Path) -> io::Result<()> {
    match fs::remove_file(rs_file) {
        Ok(()) => Ok(()),
        Err(e) => {
            // Unix reports NotFound, Windows PermissionDenied!
            match e.kind() {
                io::ErrorKind::NotFound | io::ErrorKind::PermissionDenied=> Ok(()),
                _ => Err(e),
            }
        }
    }
}

fn needs_rebuild(lalrpop_file: &Path,
                 rs_file: &Path)
                 -> io::Result<bool>
{
    return match fs::metadata(&rs_file) {
        Ok(rs_metadata) => {
            let lalrpop_metadata = try!(fs::metadata(&lalrpop_file));
            Ok(compare_modification_times(&lalrpop_metadata, &rs_metadata))
        }
        Err(e) => {
            match e.kind() {
                io::ErrorKind::NotFound => Ok(true),
                _ => Err(e),
            }
        }
    };

    #[cfg(unix)]
    fn compare_modification_times(lalrpop_metadata: &fs::Metadata,
                                  rs_metadata: &fs::Metadata)
                                  -> bool
    {
        use std::os::unix::fs::MetadataExt;
        lalrpop_metadata.mtime() >= rs_metadata.mtime()
    }

    #[cfg(windows)]
    fn compare_modification_times(lalrpop_metadata: &fs::Metadata,
                                  rs_metadata: &fs::Metadata)
                                  -> bool
    {
        use std::os::windows::fs::MetadataExt;
        lalrpop_metadata.last_write_time() >= rs_metadata.last_write_time()
    }

    #[cfg(not(any(unix,windows)))]
    fn compare_modification_times(lalrpop_metadata: &fs::Metadata,
                                  rs_metadata: &fs::Metadata)
                                  -> bool
    {
        true
    }
}

fn make_read_only(rs_file: &Path, ro: bool) -> io::Result<()> {
    if (rs_file.is_file()) {
        let rs_metadata = try!(fs::metadata(&rs_file));
        let mut rs_permissions = rs_metadata.permissions();
        rs_permissions.set_readonly(ro);
        fs::set_permissions(&rs_file, rs_permissions)
    } else {
        Ok(())
    }
}

fn lalrpop_files<P:AsRef<Path>>(root_dir: P) -> io::Result<Vec<PathBuf>> {
    let mut result = vec![];
    for entry in try!(fs::read_dir(root_dir)) {
        let entry = try!(entry);
        let file_type = try!(entry.file_type());

        let path = entry.path();

        if file_type.is_dir() {
            result.extend(try!(lalrpop_files(&path)));
        }

        if
            file_type.is_file() &&
            path.extension().is_some() &&
            path.extension().unwrap() == "lalrpop"
        {
            result.push(path);
        }
    }
    Ok(result)
}

fn parse_and_normalize_grammar(path: PathBuf) -> io::Result<r::Grammar> {
    let input = try!(FileText::from_path(path));

    let grammar = match parser::parse_grammar(input.text()) {
        Ok(grammar) => grammar,

        Err(ParseError::InvalidToken { location }) => {
            let ch = input.text()[location..].chars().next().unwrap();
            report_error(&input,
                         pt::Span(location, location),
                         &format!("invalid character `{}`", ch));
        }

        Err(ParseError::UnrecognizedToken { token: None, expected: _ }) => {
            let len = input.text().len();
            report_error(&input,
                         pt::Span(len, len),
                         &format!("unexpected end of file"));
        }

        Err(ParseError::UnrecognizedToken { token: Some((lo, _, hi)), expected }) => {
            assert!(expected.is_empty()); // didn't implement this yet :)
            let text = &input.text()[lo..hi];
            report_error(&input,
                         pt::Span(lo, hi),
                         &format!("unexpected token: `{}`", text));
        }

        Err(ParseError::ExtraToken { token: (lo, _, hi) }) => {
            let text = &input.text()[lo..hi];
            report_error(&input,
                         pt::Span(lo, hi),
                         &format!("extra token at end of input: `{}`", text));
        }

        Err(ParseError::User { error }) => {
            let string = match error.code {
                tok::ErrorCode::UnrecognizedToken =>
                    "unrecognized token",
                tok::ErrorCode::UnterminatedEscape =>
                    "unterminated escape; missing '`'?",
                tok::ErrorCode::UnterminatedStringLiteral =>
                    "unterminated string literal; missing `\"`?",
                tok::ErrorCode::ExpectedStringLiteral =>
                    "expected string literal; missing `\"`?",
                tok::ErrorCode::UnterminatedCode =>
                    "unterminated code block; perhaps a missing `;`, `)`, `]` or `}`?"
            };

            report_error(&input,
                         pt::Span(error.location, error.location + 1),
                         string)
        }
    };

    match normalize::normalize(grammar) {
        Ok(grammar) => Ok(grammar),
        Err(error) => {
            report_error(&input,
                         error.span,
                         &error.message)
        }
    }
}

fn report_error(file_text: &FileText, span: pt::Span, message: &str) -> ! {
    println!("{} error: {}", file_text.span_str(span), message);

    let out = io::stdout();
    let mut out = out.lock();
    file_text.highlight(span, &mut out).unwrap();

    exit(1);
}

fn emit_uses<W:Write>(grammar: &r::Grammar,
                      rust: &mut RustWrite<W>)
                      -> io::Result<()>
{
    rust.write_uses("", grammar)
}

fn emit_recursive_ascent(output_path: &Path, grammar: &r::Grammar) -> io::Result<()>
{
    let output_file = try!(fs::File::create(output_path));
    let mut rust = RustWrite::new(output_file);

    // We generate a module structure like this:
    //
    // ```
    // mod <output-file> {
    //     // For each public symbol:
    //     pub fn parse_XYZ();
    //     mod __XYZ { ... }
    //
    //     // For each bit of action code:
    //     <action-code>
    // }
    // ```
    //
    // Note that the action code goes in the outer module.  This is
    // intentional because it means that the foo.lalrpop file serves
    // as a module in the rust hierarchy, so if the action code
    // includes things like `super::` it will resolve in the natural
    // way.

    // often some of the uses are not used here
    rust!(rust, "#![allow(unused_imports)]");

    // we always thread the parameters through to the action code,
    // even if they are not used, and hence we need to disable the
    // unused variables lint, which otherwise gets very excited.
    if !grammar.parameters.is_empty() {
        rust!(rust, "#![allow(unused_variables)]");
    }

    try!(emit_uses(grammar, &mut rust));

    if grammar.start_nonterminals.is_empty() {
        println!("Error: no public symbols declared in grammar");
        exit(1);
    }

    for (&user_nt, &start_nt) in &grammar.start_nonterminals {
        // We generate these, so there should always be exactly 1
        // production. Otherwise the LR(1) algorithm doesn't know
        // where to stop!
        assert_eq!(grammar.productions_for(start_nt).len(), 1);

        let states = match lr1::build_states(&grammar, start_nt) {
            Ok(states) => states,
            Err(error) => {
                try!(lr1::report_error(&mut io::stdout(), &grammar, &error));
                exit(1)
            }
        };

        try!(lr1::ascent::compile(&grammar, user_nt, start_nt, &states, &mut rust));

        rust!(rust, "pub use self::{}parse{}::parse_{};",
              grammar.prefix, start_nt, user_nt);
    }

    if let Some(ref intern_token) = grammar.intern_token {
        try!(intern_token::compile(&grammar, intern_token, &mut rust));
    }

    try!(action::emit_action_code(grammar, &mut rust));

    try!(emit_to_triple_trait(grammar, &mut rust));

    Ok(())
}

fn emit_to_triple_trait<W:Write>(grammar: &r::Grammar,
                                 rust: &mut RustWrite<W>)
                                 -> io::Result<()>
{
    #![allow(non_snake_case)]

    let L = grammar.types.terminal_loc_type();
    let T = grammar.types.terminal_token_type();
    let E = grammar.types.error_type();

    let mut user_type_parameters = String::new();
    for type_parameter in &grammar.type_parameters {
        user_type_parameters.push_str(&format!("{}, ", type_parameter));
    }

    rust!(rust, "");
    rust!(rust, "pub trait {}ToTriple<{}> {{", grammar.prefix, user_type_parameters);
    rust!(rust, "type Error;");
    rust!(rust, "fn to_triple(value: Self) -> Result<({},{},{}),Self::Error>;", L, T, L);
    rust!(rust, "}}");

    rust!(rust, "");
    if grammar.types.opt_terminal_loc_type().is_some() {
        rust!(rust, "impl<{}> {}ToTriple<{}> for ({}, {}, {}) {{",
              user_type_parameters, grammar.prefix, user_type_parameters, L, T, L);
        rust!(rust, "type Error = {};", E);
        rust!(rust, "fn to_triple(value: Self) -> Result<({},{},{}),{}> {{", L, T, L, E);
        rust!(rust, "Ok(value)");
        rust!(rust, "}}");
        rust!(rust, "}}");

        rust!(rust, "impl<{}> {}ToTriple<{}> for Result<({}, {}, {}),{}> {{",
              user_type_parameters, grammar.prefix, user_type_parameters, L, T, L, E);
        rust!(rust, "type Error = {};", E);
        rust!(rust, "fn to_triple(value: Self) -> Result<({},{},{}),{}> {{", L, T, L, E);
        rust!(rust, "value");
        rust!(rust, "}}");
        rust!(rust, "}}");
    } else {
        rust!(rust, "impl<{}> {}ToTriple<{}> for {} {{",
              user_type_parameters, grammar.prefix, user_type_parameters, T);
        rust!(rust, "type Error = {};", E);
        rust!(rust, "fn to_triple(value: Self) -> Result<((),{},()),{}> {{", T, E);
        rust!(rust, "Ok(((), value, ()))");
        rust!(rust, "}}");
        rust!(rust, "}}");

        rust!(rust, "impl<{}> {}ToTriple<{}> for Result<({}),{}> {{",
              user_type_parameters, grammar.prefix, user_type_parameters, T, E);
        rust!(rust, "type Error = {};", E);
        rust!(rust, "fn to_triple(value: Self) -> Result<((),{},()),{}> {{", T, E);
        rust!(rust, "value.map(|v| ((), v, ()))");
        rust!(rust, "}}");
        rust!(rust, "}}");
    }

    Ok(())
}
<|endoftext|>


<commit_before>/*!

Sendable hash maps.  Very much a work in progress.

*/

/**
 * A function that returns a hash of a value
 *
 * The hash should concentrate entropy in the lower bits.
 */
type HashFn<K> = pure fn~(K) -> uint;
type EqFn<K> = pure fn~(K, K) -> bool;

/// Open addressing with linear probing.
mod linear {
    export LinearMap, linear_map, linear_map_with_capacity, public_methods;

    const initial_capacity: uint = 32u; // 2^5
    type Bucket<K,V> = {hash: uint, key: K, value: V};
    enum LinearMap<K,V> {
        LinearMap_({
            hashfn: pure fn~(x: &K) -> uint,
            eqfn: pure fn~(x: &K, y: &K) -> bool,
            resize_at: uint,
            size: uint,
            buckets: ~[option<Bucket<K,V>>]})
    }

    // FIXME(#3148) -- we could rewrite found_entry
    // to have type option<&bucket<K,V>> which would be nifty
    // However, that won't work until #3148 is fixed
    enum SearchResult {
        FoundEntry(uint), FoundHole(uint), TableFull
    }

    fn resize_at(capacity: uint) -> uint {
        ((capacity as float) * 3. / 4.) as uint
    }

    fn linear_map<K,V>(
        +hashfn: pure fn~(x: &K) -> uint,
        +eqfn: pure fn~(x: &K, y: &K) -> bool) -> LinearMap<K,V> {

        linear_map_with_capacity(hashfn, eqfn, 32)
    }

    fn linear_map_with_capacity<K,V>(
        +hashfn: pure fn~(x: &K) -> uint,
        +eqfn: pure fn~(x: &K, y: &K) -> bool,
        initial_capacity: uint) -> LinearMap<K,V> {

        LinearMap_({
            hashfn: hashfn,
            eqfn: eqfn,
            resize_at: resize_at(initial_capacity),
            size: 0,
            buckets: vec::from_fn(initial_capacity, |_i| none)})
    }

    priv impl<K, V> &const LinearMap<K,V> {
        #[inline(always)]
        pure fn to_bucket(h: uint) -> uint {
            // FIXME(#3041) borrow a more sophisticated technique here from
            // Gecko, for example borrowing from Knuth, as Eich so
            // colorfully argues for here:
            // https://bugzilla.mozilla.org/show_bug.cgi?id=743107#c22
            h % self.buckets.len()
        }

        #[inline(always)]
        pure fn next_bucket(idx: uint, len_buckets: uint) -> uint {
            let n = (idx + 1) % len_buckets;
            unsafe{ // argh. log not considered pure.
                debug!{"next_bucket(%?, %?) = %?", idx, len_buckets, n};
            }
            return n;
        }

        #[inline(always)]
        pure fn bucket_sequence(hash: uint, op: fn(uint) -> bool) -> uint {
            let start_idx = self.to_bucket(hash);
            let len_buckets = self.buckets.len();
            let mut idx = start_idx;
            loop {
                if !op(idx) {
                    return idx;
                }
                idx = self.next_bucket(idx, len_buckets);
                if idx == start_idx {
                    return start_idx;
                }
            }
        }

        #[inline(always)]
        pure fn bucket_for_key(
            buckets: &[option<Bucket<K,V>>],
            k: &K) -> SearchResult {

            let hash = self.hashfn(k);
            self.bucket_for_key_with_hash(buckets, hash, k)
        }

        #[inline(always)]
        pure fn bucket_for_key_with_hash(
            buckets: &[option<Bucket<K,V>>],
            hash: uint,
            k: &K) -> SearchResult {

            let _ = for self.bucket_sequence(hash) |i| {
                match buckets[i] {
                  some(bkt) => if bkt.hash == hash && self.eqfn(k, &bkt.key) {
                    return FoundEntry(i);
                  },
                  none => return FoundHole(i)
                }
            };
            return TableFull;
        }
    }

    priv impl<K,V> &mut LinearMap<K,V> {
        /// Expands the capacity of the array and re-inserts each
        /// of the existing buckets.
        fn expand() {
            let old_capacity = self.buckets.len();
            let new_capacity = old_capacity * 2;
            self.resize_at = ((new_capacity as float) * 3.0 / 4.0) as uint;

            let mut old_buckets = vec::from_fn(new_capacity, |_i| none);
            self.buckets <-> old_buckets;

            for uint::range(0, old_capacity) |i| {
                let mut bucket = none;
                bucket <-> old_buckets[i];
                if bucket.is_some() {
                    self.insert_bucket(bucket);
                }
            }
        }

        fn insert_bucket(+bucket: option<Bucket<K,V>>) {
            let {hash, key, value} <- option::unwrap(bucket);
            let _ = self.insert_internal(hash, key, value);
        }

        /// Inserts the key value pair into the buckets.
        /// Assumes that there will be a bucket.
        /// True if there was no previous entry with that key
        fn insert_internal(hash: uint, +k: K, +v: V) -> bool {
            match self.bucket_for_key_with_hash(self.buckets, hash, &k) {
              TableFull => {fail ~"Internal logic error";}
              FoundHole(idx) => {
                debug!{"insert fresh (%?->%?) at idx %?, hash %?",
                       k, v, idx, hash};
                self.buckets[idx] = some({hash: hash, key: k, value: v});
                self.size += 1;
                return true;
              }
              FoundEntry(idx) => {
                debug!{"insert overwrite (%?->%?) at idx %?, hash %?",
                       k, v, idx, hash};
                self.buckets[idx] = some({hash: hash, key: k, value: v});
                return false;
              }
            }
        }
    }

    impl<K,V> &mut LinearMap<K,V> {
        fn insert(+k: K, +v: V) -> bool {
            if self.size >= self.resize_at {
                // n.b.: We could also do this after searching, so
                // that we do not resize if this call to insert is
                // simply going to update a key in place.  My sense
                // though is that it's worse to have to search through
                // buckets to find the right spot twice than to just
                // resize in this corner case.
                self.expand();
            }

            let hash = self.hashfn(&k);
            self.insert_internal(hash, k, v)
        }

        fn remove(k: &K) -> bool {
            // Removing from an open-addressed hashtable
            // is, well, painful.  The problem is that
            // the entry may lie on the probe path for other
            // entries, so removing it would make you think that
            // those probe paths are empty.
            //
            // To address this we basically have to keep walking,
            // re-inserting entries we find until we reach an empty
            // bucket.  We know we will eventually reach one because
            // we insert one ourselves at the beginning (the removed
            // entry).
            //
            // I found this explanation elucidating:
            // http://www.maths.lse.ac.uk/Courses/MA407/del-hash.pdf

            let mut idx = match self.bucket_for_key(self.buckets, k) {
              TableFull | FoundHole(_) => {
                return false;
              }
              FoundEntry(idx) => {
                idx
              }
            };

            let len_buckets = self.buckets.len();
            self.buckets[idx] = none;
            idx = self.next_bucket(idx, len_buckets);
            while self.buckets[idx].is_some() {
                let mut bucket = none;
                bucket <-> self.buckets[idx];
                self.insert_bucket(bucket);
                idx = self.next_bucket(idx, len_buckets);
            }
            self.size -= 1;
            return true;
        }

        fn clear() {
            for uint::range(0, self.buckets.len()) |idx| {
                self.buckets[idx] = none;
            }
            self.size = 0;
        }
    }

    priv impl<K,V> &LinearMap<K,V> {
        fn search(hash: uint, op: fn(x: &option<Bucket<K,V>>) -> bool) {
            let _ = self.bucket_sequence(hash, |i| op(&self.buckets[i]));
        }
    }

    impl<K,V> &const LinearMap<K,V> {
        pure fn len() -> uint {
            self.size
        }

        pure fn is_empty() -> bool {
            self.len() == 0
        }

        fn contains_key(k: &K) -> bool {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(_) => {true}
              TableFull | FoundHole(_) => {false}
            }
        }
    }

    impl<K,V: copy> &const LinearMap<K,V> {
        fn find(k: &K) -> option<V> {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(idx) => {
                match check self.buckets[idx] {
                  some(bkt) => {some(copy bkt.value)}
                }
              }
              TableFull | FoundHole(_) => {
                none
              }
            }
        }

        fn get(k: &K) -> V {
            let value = self.find(k);
            if value.is_none() {
                fail fmt!{"No entry found for key: %?", k};
            }
            option::unwrap(value)
        }

    }

    impl<K,V> &LinearMap<K,V> {
        /*
        FIXME(#3148)--region inference fails to capture needed deps

        fn find_ref(k: &K) -> option<&self/V> {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(idx) => {
                match check self.buckets[idx] {
                  some(ref bkt) => some(&bkt.value)
                }
              }
              TableFull | FoundHole(_) => {
                none
              }
            }
        }
        */

        fn each_ref(blk: fn(k: &K, v: &V) -> bool) {
            for vec::each(self.buckets) |slot| {
                let mut broke = false;
                do slot.iter |bucket| {
                    if !blk(&bucket.key, &bucket.value) {
                        broke = true; // FIXME(#3064) just write "break;"
                    }
                }
                if broke { break; }
            }
        }
        fn each_key_ref(blk: fn(k: &K) -> bool) {
            self.each_ref(|k, _v| blk(k))
        }
        fn each_value_ref(blk: fn(v: &V) -> bool) {
            self.each_ref(|_k, v| blk(v))
        }
    }

    impl<K: copy, V: copy> &LinearMap<K,V> {
        fn each(blk: fn(+K,+V) -> bool) {
            self.each_ref(|k,v| blk(copy *k, copy *v));
        }
    }
    impl<K: copy, V> &LinearMap<K,V> {
        fn each_key(blk: fn(+K) -> bool) {
            self.each_key_ref(|k| blk(copy *k));
        }
    }
    impl<K, V: copy> &LinearMap<K,V> {
        fn each_value(blk: fn(+V) -> bool) {
            self.each_value_ref(|v| blk(copy *v));
        }
    }
}

#[test]
mod test {

    import linear::{LinearMap, linear_map};

    pure fn uint_hash(x: &uint) -> uint { *x }
    pure fn uint_eq(x: &uint, y: &uint) -> bool { *x == *y }

    fn int_linear_map<V>() -> LinearMap<uint,V> {
        return linear_map(uint_hash, uint_eq);
    }

    #[test]
    fn inserts() {
        let mut m = ~int_linear_map();
        assert m.insert(1, 2);
        assert m.insert(2, 4);
        assert m.get(&1) == 2;
        assert m.get(&2) == 4;
    }

    #[test]
    fn overwrite() {
        let mut m = ~int_linear_map();
        assert m.insert(1, 2);
        assert m.get(&1) == 2;
        assert !m.insert(1, 3);
        assert m.get(&1) == 3;
    }

    #[test]
    fn conflicts() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
        assert m.get(&1) == 2;
    }

    #[test]
    fn conflict_remove() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.remove(&1);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
    }

    #[test]
    fn empty() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert !m.is_empty();
        assert m.remove(&1);
        assert m.is_empty();
    }

    #[test]
    fn iterate() {
        let mut m = linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        for uint::range(0, 32) |i| {
            assert (&mut m).insert(i, i*2);
        }
        let mut observed = 0;
        for (&m).each |k, v| {
            assert v == k*2;
            observed |= (1 << k);
        }
        assert observed == 0xFFFF_FFFF;
    }
}
<commit_msg>Remove match check in send_map<commit_after>/*!

Sendable hash maps.  Very much a work in progress.

*/

/**
 * A function that returns a hash of a value
 *
 * The hash should concentrate entropy in the lower bits.
 */
type HashFn<K> = pure fn~(K) -> uint;
type EqFn<K> = pure fn~(K, K) -> bool;

/// Open addressing with linear probing.
mod linear {
    export LinearMap, linear_map, linear_map_with_capacity, public_methods;

    const initial_capacity: uint = 32u; // 2^5
    type Bucket<K,V> = {hash: uint, key: K, value: V};
    enum LinearMap<K,V> {
        LinearMap_({
            hashfn: pure fn~(x: &K) -> uint,
            eqfn: pure fn~(x: &K, y: &K) -> bool,
            resize_at: uint,
            size: uint,
            buckets: ~[option<Bucket<K,V>>]})
    }

    // FIXME(#3148) -- we could rewrite found_entry
    // to have type option<&bucket<K,V>> which would be nifty
    // However, that won't work until #3148 is fixed
    enum SearchResult {
        FoundEntry(uint), FoundHole(uint), TableFull
    }

    fn resize_at(capacity: uint) -> uint {
        ((capacity as float) * 3. / 4.) as uint
    }

    fn linear_map<K,V>(
        +hashfn: pure fn~(x: &K) -> uint,
        +eqfn: pure fn~(x: &K, y: &K) -> bool) -> LinearMap<K,V> {

        linear_map_with_capacity(hashfn, eqfn, 32)
    }

    fn linear_map_with_capacity<K,V>(
        +hashfn: pure fn~(x: &K) -> uint,
        +eqfn: pure fn~(x: &K, y: &K) -> bool,
        initial_capacity: uint) -> LinearMap<K,V> {

        LinearMap_({
            hashfn: hashfn,
            eqfn: eqfn,
            resize_at: resize_at(initial_capacity),
            size: 0,
            buckets: vec::from_fn(initial_capacity, |_i| none)})
    }

    priv impl<K, V> &const LinearMap<K,V> {
        #[inline(always)]
        pure fn to_bucket(h: uint) -> uint {
            // FIXME(#3041) borrow a more sophisticated technique here from
            // Gecko, for example borrowing from Knuth, as Eich so
            // colorfully argues for here:
            // https://bugzilla.mozilla.org/show_bug.cgi?id=743107#c22
            h % self.buckets.len()
        }

        #[inline(always)]
        pure fn next_bucket(idx: uint, len_buckets: uint) -> uint {
            let n = (idx + 1) % len_buckets;
            unsafe{ // argh. log not considered pure.
                debug!{"next_bucket(%?, %?) = %?", idx, len_buckets, n};
            }
            return n;
        }

        #[inline(always)]
        pure fn bucket_sequence(hash: uint, op: fn(uint) -> bool) -> uint {
            let start_idx = self.to_bucket(hash);
            let len_buckets = self.buckets.len();
            let mut idx = start_idx;
            loop {
                if !op(idx) {
                    return idx;
                }
                idx = self.next_bucket(idx, len_buckets);
                if idx == start_idx {
                    return start_idx;
                }
            }
        }

        #[inline(always)]
        pure fn bucket_for_key(
            buckets: &[option<Bucket<K,V>>],
            k: &K) -> SearchResult {

            let hash = self.hashfn(k);
            self.bucket_for_key_with_hash(buckets, hash, k)
        }

        #[inline(always)]
        pure fn bucket_for_key_with_hash(
            buckets: &[option<Bucket<K,V>>],
            hash: uint,
            k: &K) -> SearchResult {

            let _ = for self.bucket_sequence(hash) |i| {
                match buckets[i] {
                  some(bkt) => if bkt.hash == hash && self.eqfn(k, &bkt.key) {
                    return FoundEntry(i);
                  },
                  none => return FoundHole(i)
                }
            };
            return TableFull;
        }
    }

    priv impl<K,V> &mut LinearMap<K,V> {
        /// Expands the capacity of the array and re-inserts each
        /// of the existing buckets.
        fn expand() {
            let old_capacity = self.buckets.len();
            let new_capacity = old_capacity * 2;
            self.resize_at = ((new_capacity as float) * 3.0 / 4.0) as uint;

            let mut old_buckets = vec::from_fn(new_capacity, |_i| none);
            self.buckets <-> old_buckets;

            for uint::range(0, old_capacity) |i| {
                let mut bucket = none;
                bucket <-> old_buckets[i];
                if bucket.is_some() {
                    self.insert_bucket(bucket);
                }
            }
        }

        fn insert_bucket(+bucket: option<Bucket<K,V>>) {
            let {hash, key, value} <- option::unwrap(bucket);
            let _ = self.insert_internal(hash, key, value);
        }

        /// Inserts the key value pair into the buckets.
        /// Assumes that there will be a bucket.
        /// True if there was no previous entry with that key
        fn insert_internal(hash: uint, +k: K, +v: V) -> bool {
            match self.bucket_for_key_with_hash(self.buckets, hash, &k) {
              TableFull => {fail ~"Internal logic error";}
              FoundHole(idx) => {
                debug!{"insert fresh (%?->%?) at idx %?, hash %?",
                       k, v, idx, hash};
                self.buckets[idx] = some({hash: hash, key: k, value: v});
                self.size += 1;
                return true;
              }
              FoundEntry(idx) => {
                debug!{"insert overwrite (%?->%?) at idx %?, hash %?",
                       k, v, idx, hash};
                self.buckets[idx] = some({hash: hash, key: k, value: v});
                return false;
              }
            }
        }
    }

    impl<K,V> &mut LinearMap<K,V> {
        fn insert(+k: K, +v: V) -> bool {
            if self.size >= self.resize_at {
                // n.b.: We could also do this after searching, so
                // that we do not resize if this call to insert is
                // simply going to update a key in place.  My sense
                // though is that it's worse to have to search through
                // buckets to find the right spot twice than to just
                // resize in this corner case.
                self.expand();
            }

            let hash = self.hashfn(&k);
            self.insert_internal(hash, k, v)
        }

        fn remove(k: &K) -> bool {
            // Removing from an open-addressed hashtable
            // is, well, painful.  The problem is that
            // the entry may lie on the probe path for other
            // entries, so removing it would make you think that
            // those probe paths are empty.
            //
            // To address this we basically have to keep walking,
            // re-inserting entries we find until we reach an empty
            // bucket.  We know we will eventually reach one because
            // we insert one ourselves at the beginning (the removed
            // entry).
            //
            // I found this explanation elucidating:
            // http://www.maths.lse.ac.uk/Courses/MA407/del-hash.pdf

            let mut idx = match self.bucket_for_key(self.buckets, k) {
              TableFull | FoundHole(_) => {
                return false;
              }
              FoundEntry(idx) => {
                idx
              }
            };

            let len_buckets = self.buckets.len();
            self.buckets[idx] = none;
            idx = self.next_bucket(idx, len_buckets);
            while self.buckets[idx].is_some() {
                let mut bucket = none;
                bucket <-> self.buckets[idx];
                self.insert_bucket(bucket);
                idx = self.next_bucket(idx, len_buckets);
            }
            self.size -= 1;
            return true;
        }

        fn clear() {
            for uint::range(0, self.buckets.len()) |idx| {
                self.buckets[idx] = none;
            }
            self.size = 0;
        }
    }

    priv impl<K,V> &LinearMap<K,V> {
        fn search(hash: uint, op: fn(x: &option<Bucket<K,V>>) -> bool) {
            let _ = self.bucket_sequence(hash, |i| op(&self.buckets[i]));
        }
    }

    impl<K,V> &const LinearMap<K,V> {
        pure fn len() -> uint {
            self.size
        }

        pure fn is_empty() -> bool {
            self.len() == 0
        }

        fn contains_key(k: &K) -> bool {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(_) => {true}
              TableFull | FoundHole(_) => {false}
            }
        }
    }

    impl<K,V: copy> &const LinearMap<K,V> {
        fn find(k: &K) -> option<V> {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(idx) => {
                match self.buckets[idx] {
                  some(bkt) => {some(copy bkt.value)}
                  // FIXME (#3148): Will be able to get rid of this when we
                  // redefine SearchResult
                  none      => fail ~"LinearMap::find: internal logic error"
                }
              }
              TableFull | FoundHole(_) => {
                none
              }
            }
        }

        fn get(k: &K) -> V {
            let value = self.find(k);
            if value.is_none() {
                fail fmt!{"No entry found for key: %?", k};
            }
            option::unwrap(value)
        }

    }

    impl<K,V> &LinearMap<K,V> {
        /*
        FIXME(#3148)--region inference fails to capture needed deps

        fn find_ref(k: &K) -> option<&self/V> {
            match self.bucket_for_key(self.buckets, k) {
              FoundEntry(idx) => {
                match check self.buckets[idx] {
                  some(ref bkt) => some(&bkt.value)
                }
              }
              TableFull | FoundHole(_) => {
                none
              }
            }
        }
        */

        fn each_ref(blk: fn(k: &K, v: &V) -> bool) {
            for vec::each(self.buckets) |slot| {
                let mut broke = false;
                do slot.iter |bucket| {
                    if !blk(&bucket.key, &bucket.value) {
                        broke = true; // FIXME(#3064) just write "break;"
                    }
                }
                if broke { break; }
            }
        }
        fn each_key_ref(blk: fn(k: &K) -> bool) {
            self.each_ref(|k, _v| blk(k))
        }
        fn each_value_ref(blk: fn(v: &V) -> bool) {
            self.each_ref(|_k, v| blk(v))
        }
    }

    impl<K: copy, V: copy> &LinearMap<K,V> {
        fn each(blk: fn(+K,+V) -> bool) {
            self.each_ref(|k,v| blk(copy *k, copy *v));
        }
    }
    impl<K: copy, V> &LinearMap<K,V> {
        fn each_key(blk: fn(+K) -> bool) {
            self.each_key_ref(|k| blk(copy *k));
        }
    }
    impl<K, V: copy> &LinearMap<K,V> {
        fn each_value(blk: fn(+V) -> bool) {
            self.each_value_ref(|v| blk(copy *v));
        }
    }
}

#[test]
mod test {

    import linear::{LinearMap, linear_map};

    pure fn uint_hash(x: &uint) -> uint { *x }
    pure fn uint_eq(x: &uint, y: &uint) -> bool { *x == *y }

    fn int_linear_map<V>() -> LinearMap<uint,V> {
        return linear_map(uint_hash, uint_eq);
    }

    #[test]
    fn inserts() {
        let mut m = ~int_linear_map();
        assert m.insert(1, 2);
        assert m.insert(2, 4);
        assert m.get(&1) == 2;
        assert m.get(&2) == 4;
    }

    #[test]
    fn overwrite() {
        let mut m = ~int_linear_map();
        assert m.insert(1, 2);
        assert m.get(&1) == 2;
        assert !m.insert(1, 3);
        assert m.get(&1) == 3;
    }

    #[test]
    fn conflicts() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
        assert m.get(&1) == 2;
    }

    #[test]
    fn conflict_remove() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert m.insert(5, 3);
        assert m.insert(9, 4);
        assert m.remove(&1);
        assert m.get(&9) == 4;
        assert m.get(&5) == 3;
    }

    #[test]
    fn empty() {
        let mut m = ~linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        assert m.insert(1, 2);
        assert !m.is_empty();
        assert m.remove(&1);
        assert m.is_empty();
    }

    #[test]
    fn iterate() {
        let mut m = linear::linear_map_with_capacity(uint_hash, uint_eq, 4);
        for uint::range(0, 32) |i| {
            assert (&mut m).insert(i, i*2);
        }
        let mut observed = 0;
        for (&m).each |k, v| {
            assert v == k*2;
            observed |= (1 << k);
        }
        assert observed == 0xFFFF_FFFF;
    }
}
<|endoftext|>


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

use super::*;
use crate::message::BufferMessageEncoder;
use futures::prelude::*;
use futures::task::{Waker, Poll};
use futures_timer::Delay;
use std::cell::Cell;
use std::fmt::{Display, Formatter};
use std::ops::Bound;
use std::pin::Pin;
use std::sync::{Arc, Mutex, Weak};
use std::time::{Duration, Instant};

#[derive(Debug, Eq, PartialEq, Hash, Clone)]
pub(super) enum UdpSendFutureState<R> {
    /// This send future hasn't been polled yet.
    Uninit,

    /// We are waiting for either an Ack or a response, and we will retransmit
    /// occasionally.
    ActivelyWaiting,

    /// We are still waiting for a response. We are not retransmitting.
    PassivelyWaiting,

    /// We are finished and waiting for our final result to be polled.
    Finished(Result<R, Error>),

    /// We are completely finished.
    Expired,
}

impl<R> Display for UdpSendFutureState<R> {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
        match self {
            UdpSendFutureState::Uninit => f.write_str("Uninit"),
            UdpSendFutureState::ActivelyWaiting => f.write_str("ActivelyWaiting"),
            UdpSendFutureState::PassivelyWaiting => f.write_str("PassivelyWaiting"),
            UdpSendFutureState::Finished(Ok(_)) => f.write_str("Finished"),
            UdpSendFutureState::Finished(Err(e)) => write!(f, "Errored({:?})", e),
            UdpSendFutureState::Expired => f.write_str("Expired"),
        }
    }
}

impl<R> UdpSendFutureState<R> {
    pub fn is_waiting(&self) -> bool {
        match self {
            UdpSendFutureState::ActivelyWaiting | UdpSendFutureState::PassivelyWaiting => true,
            _ => false,
        }
    }

    pub fn is_finished(&self) -> bool {
        match self {
            UdpSendFutureState::Finished(_) | UdpSendFutureState::Expired => true,
            _ => false,
        }
    }

    pub fn finished(self) -> Option<Result<R, Error>> {
        match self {
            UdpSendFutureState::Finished(x) => Some(x),
            _ => None,
        }
    }
}

pub(super) struct UdpSendFutureInner<R, SD, US, TP>
where
    R: Send,
    SD: SendDesc<DatagramInboundContext<US::SocketAddr>, R>,
    US: AsyncDatagramSocket,
    TP: TransParams,
{
    send_desc: SD,
    state: UdpSendFutureState<R>,
    waker: Option<futures::task::Waker>,
    local_endpoint: Weak<DatagramLocalEndpointInner<US>>,
    dest: US::SocketAddr,

    msg_id: MsgId,
    msg_token: Cell<MsgToken>,
    retransmit_count: Cell<u32>,
    delay: Option<Delay>,
    timeout: Cell<Option<Instant>>,
    _trans_params: TP, // <datagram::DatagramLocalEndpoint<US> as LocalEndpoint>::DefaultTransParams
}

impl<R, SD, US, TP> UdpSendFutureInner<R, SD, US, TP>
where
    R: Send,
    SD: SendDesc<DatagramInboundContext<US::SocketAddr>, R>,
    US: AsyncDatagramSocket + Sized,
    TP: TransParams,
{
    fn state(&self) -> &UdpSendFutureState<R> {
        &self.state
    }

    fn change_state(&mut self, mut state: UdpSendFutureState<R>) -> UdpSendFutureState<R> {
        if state.is_finished() {
            self.update_timeout(None);
        }
        std::mem::swap(&mut self.state, &mut state);
        state
    }

    fn update_waker(&mut self, waker_ref: &Waker) {
        if let Some(waker) = self.waker.take() {
            self.waker = Some(if waker_ref.will_wake(&waker) {
                waker
            } else {
                waker_ref.clone()
            });
        } else {
            self.waker = Some(waker_ref.clone());
        }
    }

    fn update_timeout(&mut self, d: Option<Duration>) {
        if let Some(d) = d {
            if let Some(delay) = self.delay.as_mut() {
                delay.reset(Instant::now() + d);
            } else {
                self.delay = Some(Delay::new(d));
            }
        } else {
            self.delay = None;
        }
    }

    fn poll_timeout(
        &mut self,
        cx: &mut futures::task::Context<'_>,
    ) -> Poll<()> {
        if let Some(delay) = self.delay.as_mut() {
            Pin::new(delay).poll(cx)
        } else {
            Poll::Pending
        }
    }

    pub fn transmit(&self) -> Result<(), Error> {
        let mut buffer = [0u8; StandardCoapConstants::MAX_OUTBOUND_PACKET_LENGTH];
        let mut builder = BufferMessageEncoder::new(&mut buffer);

        let mut token = self.msg_token.get();

        if token.is_empty() {
            token = MsgToken::from(self.msg_id);
        }

        builder.set_msg_token(token);

        self.send_desc.write_options(
            &mut builder,
            &self.dest,
            Bound::Unbounded,
            Bound::Unbounded,
        )?;
        self.send_desc.write_payload(&mut builder, &self.dest)?;

        let builder_token = builder.msg_token();

        self.msg_token.replace(builder_token);

        // We always control the msg_id.
        builder.set_msg_id(self.msg_id);

        println!("OUTBOUND: {} {}", self.dest, builder);

        let buffer: &[u8] = &builder;

        if let Some(e) = self
            .local_endpoint
            .upgrade()
            .ok_or(Error::Cancelled)?
            .socket()
            .send_to(&buffer, self.dest)
            .now_or_never()
            .expect("send_to blocked")
            .err()
        {
            println!("send_to: io error: {:?} (dest={:?})", e, self.dest);
            return Err(Error::IOError);
        }

        println!("Did transmit.");

        self.retransmit_count.set(0);

        Ok(())
    }

    pub fn retransmit(&self) -> Result<(), Error> {
        let mut buffer = [0u8; StandardCoapConstants::MAX_OUTBOUND_PACKET_LENGTH];
        let mut builder = BufferMessageEncoder::new(&mut buffer);

        if let Some(timeout) = self.timeout.get() {
            if Instant::now() > timeout {
                return Err(Error::ResponseTimeout);
            }
        }

        builder.set_msg_token(self.msg_token.get());

        self.send_desc.write_options(
            &mut builder,
            &self.dest,
            Bound::Unbounded,
            Bound::Unbounded,
        )?;
        self.send_desc.write_payload(&mut builder, &self.dest)?;

        builder.set_msg_id(self.msg_id);

        println!(
            "OUTBOUND[{}]: {} {}",
            self.retransmit_count.get() + 1,
            self.dest,
            builder
        );

        let buffer: &[u8] = &builder;

        if let Some(e) = self
            .local_endpoint
            .upgrade()
            .ok_or(Error::Cancelled)?
            .socket()
            .send_to(buffer, self.dest)
            .now_or_never()
            .expect("send_to blocked")
            .err()
        {
            println!("send_to: io error: {:?} (dest={:?})", e, self.dest);
            return Err(Error::IOError);
        }

        self.retransmit_count.set(self.retransmit_count.get() + 1);

        println!("Did retransmit, count {}", self.retransmit_count.get());

        Ok(())
    }

    fn wake(&mut self) {
        if let Some(waker) = self.waker.take() {
            waker.wake();
        }
    }
}

impl<R, SD, US, TP> HandleResponse<DatagramInboundContext<US::SocketAddr>>
    for UdpSendFutureInner<R, SD, US, TP>
where
    R: Send,
    SD: SendDesc<DatagramInboundContext<US::SocketAddr>, R>,
    US: AsyncDatagramSocket,
    TP: TransParams,
{
    fn handle_response(&mut self, context: Result<&DatagramInboundContext<US::SocketAddr>, Error>) -> bool {
        // This should only be called if we are waiting for a response.
        assert!(self.state().is_waiting(), "Invalid state: {}", self.state());

        // If this is an ack, we don't pass this along to the send_desc.
        if let Some(context) = context.ok() {
            let message = context.message();

            if !self.dest.is_multicast()
                && message.msg_code().is_empty()
                && message.msg_type().is_ack()
            {
                println!("Got ack!");

                self.change_state(UdpSendFutureState::PassivelyWaiting);
                let d = self.send_desc.max_rtt();
                self.update_timeout(Some(d));
                self.wake();
                return self.state.is_finished();
            }
        }

        // Pass the full context along to our `send_desc.handler()`
        match self.send_desc.handler(context) {
            Ok(ResponseStatus::Done(x)) => {
                // Stick a fork in us, we are done.
                self.change_state(UdpSendFutureState::Finished(Ok(x)));
            }
            Ok(ResponseStatus::Continue) => {
                if !self.dest.is_multicast() {
                    self.change_state(UdpSendFutureState::PassivelyWaiting);
                    let d = self.send_desc.max_rtt();
                    self.update_timeout(Some(d));
                }
            }
            Ok(ResponseStatus::SendNext) => {
                // Allocate a new msg-id, Reset retransmit count, and resend.
                self.change_state(UdpSendFutureState::Uninit);
            }
            Err(e) => {
                self.change_state(UdpSendFutureState::Finished(Err(e)));
            }
        }

        self.wake();

        self.state.is_finished()
    }
}

pub(super) struct UdpSendFuture<R, SD, US, TP>
where
    R: Send,
    SD: SendDesc<DatagramInboundContext<US::SocketAddr>, R>,
    US: AsyncDatagramSocket,
    TP: TransParams,
{
    inner: Arc<Mutex<UdpSendFutureInner<R, SD, US, TP>>>,
}

impl<'lep, R, SD, US, TP> UdpSendFuture<R, SD, US, TP>
where
    R: Send,
    SD: SendDesc<DatagramInboundContext<US::SocketAddr>, R>,
    US: AsyncDatagramSocket,
    TP: TransParams,
{
    pub(super) fn new(
        local_endpoint: &Arc<DatagramLocalEndpointInner<US>>,
        dest: US::SocketAddr,
        send_desc: SD,
        trans_params: TP,
    ) -> UdpSendFuture<R, SD, US, TP> {
        UdpSendFuture {
            inner: Arc::new(Mutex::new(UdpSendFutureInner {
                send_desc,
                state: UdpSendFutureState::Uninit,
                waker: None,
                msg_id: local_endpoint.next_msg_id(),
                msg_token: Cell::new(MsgToken::EMPTY),
                local_endpoint: Arc::downgrade(&local_endpoint),
                dest,
                retransmit_count: Cell::new(0),
                delay: None,
                timeout: Cell::new(None),
                _trans_params: trans_params,
            })),
        }
    }

    fn poll(
        &mut self,
        cx: &mut futures::task::Context<'_>,
    ) -> futures::task::Poll<Result<R, Error>> {
        let mut inner = self
            .inner
            .lock()
            .expect("UdpSendFuture inner mutex poisoned");

        match inner.state() {
            UdpSendFutureState::Uninit => {
                // TODO(#4): Figure out how this can be set programmatically.
                inner.timeout.set(Some(
                    Instant::now() + inner.send_desc.transmit_wait_duration(),
                ));

                if let Some(error) = inner.transmit().err() {
                    inner.change_state(UdpSendFutureState::Finished(Err(error)));
                } else {
                    inner
                        .local_endpoint
                        .upgrade()
                        .ok_or(Error::Cancelled)?
                        .add_response_handler(
                            inner.msg_id,
                            inner.msg_token.get(),
                            inner.dest.clone(),
                            self.inner.clone(),
                        );

                    if let Some(d) = inner
                        .send_desc
                        .delay_to_retransmit(inner.retransmit_count.get())
                    {
                        inner.change_state(UdpSendFutureState::ActivelyWaiting);
                        inner.update_timeout(Some(d));
                        let _ = inner.poll_timeout(cx);
                    } else {
                        inner.change_state(UdpSendFutureState::PassivelyWaiting);
                        let d = inner.send_desc.max_rtt();
                        inner.update_timeout(Some(d));
                        let _ = inner.poll_timeout(cx);
                    }
                }
            }

            UdpSendFutureState::ActivelyWaiting => {
                // We are waiting to retransmit.
                if inner.poll_timeout(cx).is_ready() {
                    if let Some(error) = inner.retransmit().err() {
                        inner.change_state(UdpSendFutureState::Finished(Err(error)));
                    } else if let Some(d) = inner
                        .send_desc
                        .delay_to_retransmit(inner.retransmit_count.get())
                    {
                        inner.update_timeout(Some(d));
                        let _ = inner.poll_timeout(cx);
                    } else {
                        inner.change_state(UdpSendFutureState::PassivelyWaiting);
                        let d = inner.send_desc.max_rtt();
                        inner.update_timeout(Some(d));
                        let _ = inner.poll_timeout(cx);
                    }
                }
            }

            UdpSendFutureState::PassivelyWaiting => {
                // We are waiting for the end of the RTT
                if inner.poll_timeout(cx).is_ready() {
                    inner.handle_response(Err(Error::ResponseTimeout));
                }
            }

            UdpSendFutureState::Finished(_) | UdpSendFutureState::Expired => {
                // We are done, nothing to do here.
            }
        }

        if inner.state().is_finished() {
            let ret = inner
                .change_state(UdpSendFutureState::Expired)
                .finished()
                .unwrap();
            futures::task::Poll::Ready(ret)
        } else {
            inner.update_waker(cx.waker());

            futures::task::Poll::Pending
        }
    }
}

impl<R, SD, US, TP> Drop for UdpSendFuture<R, SD, US, TP>
where
    R: Send,
    SD: SendDesc<DatagramInboundContext<US::SocketAddr>, R>,
    US: AsyncDatagramSocket,
    TP: TransParams,
{
    fn drop(&mut self) {
        let inner = match self.inner.lock() {
            Ok(guard) => guard,
            Err(poisoned) => {
                eprintln!("UdpSendFuture mutex inner was poisoned, locking anyway to drop");
                poisoned.into_inner()
            }
        };

        if let Some(le) = inner.local_endpoint.upgrade() {
            le.remove_response_handler(inner.msg_id, inner.msg_token.get(), inner.dest.clone());
        }
    }
}

impl<R, SD, US, TP> Future for UdpSendFuture<R, SD, US, TP>
where
    R: Send,
    SD: SendDesc<DatagramInboundContext<US::SocketAddr>, R>,
    US: AsyncDatagramSocket,
    TP: TransParams,
{
    type Output = Result<R, Error>;

    fn poll(
        self: Pin<&mut Self>,
        cx: &mut futures::task::Context<'_>,
    ) -> futures::task::Poll<Self::Output> {
        self.get_mut().poll(cx)
    }
}
<commit_msg>async-coap/datagram: Fix for MID not changing during block2<commit_after>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

use super::*;
use crate::message::BufferMessageEncoder;
use futures::prelude::*;
use futures::task::{Waker, Poll};
use futures_timer::Delay;
use std::cell::Cell;
use std::fmt::{Display, Formatter};
use std::ops::Bound;
use std::pin::Pin;
use std::sync::{Arc, Mutex, Weak};
use std::time::{Duration, Instant};

#[derive(Debug, Eq, PartialEq, Hash, Clone)]
pub(super) enum UdpSendFutureState<R> {
    /// This send future hasn't been polled yet.
    Uninit,

    /// We are waiting for either an Ack or a response, and we will retransmit
    /// occasionally.
    ActivelyWaiting,

    /// We are still waiting for a response. We are not retransmitting.
    PassivelyWaiting,

    /// We are finished and waiting for our final result to be polled.
    Finished(Result<R, Error>),

    /// We are completely finished.
    Expired,
}

impl<R> Display for UdpSendFutureState<R> {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
        match self {
            UdpSendFutureState::Uninit => f.write_str("Uninit"),
            UdpSendFutureState::ActivelyWaiting => f.write_str("ActivelyWaiting"),
            UdpSendFutureState::PassivelyWaiting => f.write_str("PassivelyWaiting"),
            UdpSendFutureState::Finished(Ok(_)) => f.write_str("Finished"),
            UdpSendFutureState::Finished(Err(e)) => write!(f, "Errored({:?})", e),
            UdpSendFutureState::Expired => f.write_str("Expired"),
        }
    }
}

impl<R> UdpSendFutureState<R> {
    pub fn is_waiting(&self) -> bool {
        match self {
            UdpSendFutureState::ActivelyWaiting | UdpSendFutureState::PassivelyWaiting => true,
            _ => false,
        }
    }

    pub fn is_finished(&self) -> bool {
        match self {
            UdpSendFutureState::Finished(_) | UdpSendFutureState::Expired => true,
            _ => false,
        }
    }

    pub fn finished(self) -> Option<Result<R, Error>> {
        match self {
            UdpSendFutureState::Finished(x) => Some(x),
            _ => None,
        }
    }
}

pub(super) struct UdpSendFutureInner<R, SD, US, TP>
where
    R: Send,
    SD: SendDesc<DatagramInboundContext<US::SocketAddr>, R>,
    US: AsyncDatagramSocket,
    TP: TransParams,
{
    send_desc: SD,
    state: UdpSendFutureState<R>,
    waker: Option<futures::task::Waker>,
    local_endpoint: Weak<DatagramLocalEndpointInner<US>>,
    dest: US::SocketAddr,

    msg_id: Cell<MsgId>,
    msg_token: Cell<MsgToken>,
    retransmit_count: Cell<u32>,
    delay: Option<Delay>,
    timeout: Cell<Option<Instant>>,
    _trans_params: TP, // <datagram::DatagramLocalEndpoint<US> as LocalEndpoint>::DefaultTransParams
}

impl<R, SD, US, TP> UdpSendFutureInner<R, SD, US, TP>
where
    R: Send,
    SD: SendDesc<DatagramInboundContext<US::SocketAddr>, R>,
    US: AsyncDatagramSocket + Sized,
    TP: TransParams,
{
    fn state(&self) -> &UdpSendFutureState<R> {
        &self.state
    }

    fn change_state(&mut self, mut state: UdpSendFutureState<R>) -> UdpSendFutureState<R> {
        if state.is_finished() {
            self.update_timeout(None);
        }
        std::mem::swap(&mut self.state, &mut state);
        state
    }

    fn update_waker(&mut self, waker_ref: &Waker) {
        if let Some(waker) = self.waker.take() {
            self.waker = Some(if waker_ref.will_wake(&waker) {
                waker
            } else {
                waker_ref.clone()
            });
        } else {
            self.waker = Some(waker_ref.clone());
        }
    }

    fn update_timeout(&mut self, d: Option<Duration>) {
        if let Some(d) = d {
            if let Some(delay) = self.delay.as_mut() {
                delay.reset(Instant::now() + d);
            } else {
                self.delay = Some(Delay::new(d));
            }
        } else {
            self.delay = None;
        }
    }

    fn poll_timeout(
        &mut self,
        cx: &mut futures::task::Context<'_>,
    ) -> Poll<()> {
        if let Some(delay) = self.delay.as_mut() {
            Pin::new(delay).poll(cx)
        } else {
            Poll::Pending
        }
    }

    pub fn transmit(&self) -> Result<(), Error> {
        let mut buffer = [0u8; StandardCoapConstants::MAX_OUTBOUND_PACKET_LENGTH];
        let mut builder = BufferMessageEncoder::new(&mut buffer);

        let mut token = self.msg_token.get();

        // We allocate a new msg_id for every call to `transmit()`.
        self.msg_id.replace(self.local_endpoint
            .upgrade()
            .ok_or(Error::Cancelled)?
            .next_msg_id()
        );

        if token.is_empty() {
            token = MsgToken::from(self.msg_id.get());
        }

        builder.set_msg_token(token);

        self.send_desc.write_options(
            &mut builder,
            &self.dest,
            Bound::Unbounded,
            Bound::Unbounded,
        )?;
        self.send_desc.write_payload(&mut builder, &self.dest)?;

        let builder_token = builder.msg_token();

        self.msg_token.replace(builder_token);

        // We always control the msg_id.
        builder.set_msg_id(self.msg_id.get());

        println!("OUTBOUND: {} {}", self.dest, builder);

        let buffer: &[u8] = &builder;

        if let Some(e) = self
            .local_endpoint
            .upgrade()
            .ok_or(Error::Cancelled)?
            .socket()
            .send_to(&buffer, self.dest)
            .now_or_never()
            .expect("send_to blocked")
            .err()
        {
            println!("send_to: io error: {:?} (dest={:?})", e, self.dest);
            return Err(Error::IOError);
        }

        println!("Did transmit.");

        self.retransmit_count.set(0);

        Ok(())
    }

    pub fn retransmit(&self) -> Result<(), Error> {
        let mut buffer = [0u8; StandardCoapConstants::MAX_OUTBOUND_PACKET_LENGTH];
        let mut builder = BufferMessageEncoder::new(&mut buffer);

        if let Some(timeout) = self.timeout.get() {
            if Instant::now() > timeout {
                return Err(Error::ResponseTimeout);
            }
        }

        builder.set_msg_token(self.msg_token.get());

        self.send_desc.write_options(
            &mut builder,
            &self.dest,
            Bound::Unbounded,
            Bound::Unbounded,
        )?;
        self.send_desc.write_payload(&mut builder, &self.dest)?;

        builder.set_msg_id(self.msg_id.get());

        println!(
            "OUTBOUND[{}]: {} {}",
            self.retransmit_count.get() + 1,
            self.dest,
            builder
        );

        let buffer: &[u8] = &builder;

        if let Some(e) = self
            .local_endpoint
            .upgrade()
            .ok_or(Error::Cancelled)?
            .socket()
            .send_to(buffer, self.dest)
            .now_or_never()
            .expect("send_to blocked")
            .err()
        {
            println!("send_to: io error: {:?} (dest={:?})", e, self.dest);
            return Err(Error::IOError);
        }

        self.retransmit_count.set(self.retransmit_count.get() + 1);

        println!("Did retransmit, count {}", self.retransmit_count.get());

        Ok(())
    }

    fn wake(&mut self) {
        if let Some(waker) = self.waker.take() {
            waker.wake();
        }
    }
}

impl<R, SD, US, TP> HandleResponse<DatagramInboundContext<US::SocketAddr>>
    for UdpSendFutureInner<R, SD, US, TP>
where
    R: Send,
    SD: SendDesc<DatagramInboundContext<US::SocketAddr>, R>,
    US: AsyncDatagramSocket,
    TP: TransParams,
{
    fn handle_response(&mut self, context: Result<&DatagramInboundContext<US::SocketAddr>, Error>) -> bool {
        // This should only be called if we are waiting for a response.
        assert!(self.state().is_waiting(), "Invalid state: {}", self.state());

        // If this is an ack, we don't pass this along to the send_desc.
        if let Some(context) = context.ok() {
            let message = context.message();

            if !self.dest.is_multicast()
                && message.msg_code().is_empty()
                && message.msg_type().is_ack()
            {
                println!("Got ack!");

                self.change_state(UdpSendFutureState::PassivelyWaiting);
                let d = self.send_desc.max_rtt();
                self.update_timeout(Some(d));
                self.wake();
                return self.state.is_finished();
            }
        }

        // Pass the full context along to our `send_desc.handler()`
        match self.send_desc.handler(context) {
            Ok(ResponseStatus::Done(x)) => {
                // Stick a fork in us, we are done.
                self.change_state(UdpSendFutureState::Finished(Ok(x)));
            }
            Ok(ResponseStatus::Continue) => {
                if !self.dest.is_multicast() {
                    self.change_state(UdpSendFutureState::PassivelyWaiting);
                    let d = self.send_desc.max_rtt();
                    self.update_timeout(Some(d));
                }
            }
            Ok(ResponseStatus::SendNext) => {
                // Allocate a new msg-id, Reset retransmit count, and resend.
                self.change_state(UdpSendFutureState::Uninit);
            }
            Err(e) => {
                self.change_state(UdpSendFutureState::Finished(Err(e)));
            }
        }

        self.wake();

        self.state.is_finished()
    }
}

pub(super) struct UdpSendFuture<R, SD, US, TP>
where
    R: Send,
    SD: SendDesc<DatagramInboundContext<US::SocketAddr>, R>,
    US: AsyncDatagramSocket,
    TP: TransParams,
{
    inner: Arc<Mutex<UdpSendFutureInner<R, SD, US, TP>>>,
}

impl<'lep, R, SD, US, TP> UdpSendFuture<R, SD, US, TP>
where
    R: Send,
    SD: SendDesc<DatagramInboundContext<US::SocketAddr>, R>,
    US: AsyncDatagramSocket,
    TP: TransParams,
{
    pub(super) fn new(
        local_endpoint: &Arc<DatagramLocalEndpointInner<US>>,
        dest: US::SocketAddr,
        send_desc: SD,
        trans_params: TP,
    ) -> UdpSendFuture<R, SD, US, TP> {
        UdpSendFuture {
            inner: Arc::new(Mutex::new(UdpSendFutureInner {
                send_desc,
                state: UdpSendFutureState::Uninit,
                waker: None,
                msg_id: Cell::new(0),
                msg_token: Cell::new(MsgToken::EMPTY),
                local_endpoint: Arc::downgrade(&local_endpoint),
                dest,
                retransmit_count: Cell::new(0),
                delay: None,
                timeout: Cell::new(None),
                _trans_params: trans_params,
            })),
        }
    }

    fn poll(
        &mut self,
        cx: &mut futures::task::Context<'_>,
    ) -> futures::task::Poll<Result<R, Error>> {
        let mut inner = self
            .inner
            .lock()
            .expect("UdpSendFuture inner mutex poisoned");

        match inner.state() {
            UdpSendFutureState::Uninit => {
                // TODO(#4): Figure out how this can be set programmatically.
                inner.timeout.set(Some(
                    Instant::now() + inner.send_desc.transmit_wait_duration(),
                ));

                if let Some(error) = inner.transmit().err() {
                    inner.change_state(UdpSendFutureState::Finished(Err(error)));
                } else {
                    inner
                        .local_endpoint
                        .upgrade()
                        .ok_or(Error::Cancelled)?
                        .add_response_handler(
                            inner.msg_id.get(),
                            inner.msg_token.get(),
                            inner.dest.clone(),
                            self.inner.clone(),
                        );

                    if let Some(d) = inner
                        .send_desc
                        .delay_to_retransmit(inner.retransmit_count.get())
                    {
                        inner.change_state(UdpSendFutureState::ActivelyWaiting);
                        inner.update_timeout(Some(d));
                        let _ = inner.poll_timeout(cx);
                    } else {
                        inner.change_state(UdpSendFutureState::PassivelyWaiting);
                        let d = inner.send_desc.max_rtt();
                        inner.update_timeout(Some(d));
                        let _ = inner.poll_timeout(cx);
                    }
                }
            }

            UdpSendFutureState::ActivelyWaiting => {
                // We are waiting to retransmit.
                if inner.poll_timeout(cx).is_ready() {
                    if let Some(error) = inner.retransmit().err() {
                        inner.change_state(UdpSendFutureState::Finished(Err(error)));
                    } else if let Some(d) = inner
                        .send_desc
                        .delay_to_retransmit(inner.retransmit_count.get())
                    {
                        inner.update_timeout(Some(d));
                        let _ = inner.poll_timeout(cx);
                    } else {
                        inner.change_state(UdpSendFutureState::PassivelyWaiting);
                        let d = inner.send_desc.max_rtt();
                        inner.update_timeout(Some(d));
                        let _ = inner.poll_timeout(cx);
                    }
                }
            }

            UdpSendFutureState::PassivelyWaiting => {
                // We are waiting for the end of the RTT
                if inner.poll_timeout(cx).is_ready() {
                    inner.handle_response(Err(Error::ResponseTimeout));
                }
            }

            UdpSendFutureState::Finished(_) | UdpSendFutureState::Expired => {
                // We are done, nothing to do here.
            }
        }

        if inner.state().is_finished() {
            let ret = inner
                .change_state(UdpSendFutureState::Expired)
                .finished()
                .unwrap();
            futures::task::Poll::Ready(ret)
        } else {
            inner.update_waker(cx.waker());

            futures::task::Poll::Pending
        }
    }
}

impl<R, SD, US, TP> Drop for UdpSendFuture<R, SD, US, TP>
where
    R: Send,
    SD: SendDesc<DatagramInboundContext<US::SocketAddr>, R>,
    US: AsyncDatagramSocket,
    TP: TransParams,
{
    fn drop(&mut self) {
        let inner = match self.inner.lock() {
            Ok(guard) => guard,
            Err(poisoned) => {
                eprintln!("UdpSendFuture mutex inner was poisoned, locking anyway to drop");
                poisoned.into_inner()
            }
        };

        if let Some(le) = inner.local_endpoint.upgrade() {
            le.remove_response_handler(inner.msg_id.get(), inner.msg_token.get(), inner.dest.clone());
        }
    }
}

impl<R, SD, US, TP> Future for UdpSendFuture<R, SD, US, TP>
where
    R: Send,
    SD: SendDesc<DatagramInboundContext<US::SocketAddr>, R>,
    US: AsyncDatagramSocket,
    TP: TransParams,
{
    type Output = Result<R, Error>;

    fn poll(
        self: Pin<&mut Self>,
        cx: &mut futures::task::Context<'_>,
    ) -> futures::task::Poll<Self::Output> {
        self.get_mut().poll(cx)
    }
}
<|endoftext|>


<commit_before>pub use std::cmp::Ordering;

#[macro_export]
macro_rules! order_by_key {
    ($name:ident: $(fn ($($gen:tt)*) ($entry:ident: $t:ty) -> $r:ty $blk:block)*) => (
        #[derive(Debug, Clone, Copy)]
        struct $name;

        $(impl<$($gen)*> $crate::SortOrder<$t> for $name
        {
            fn cmp(a: &$t, b: &$t) -> $crate::macro_sort_order::Ordering {
                fn key<$($gen)*>($entry: &$t) -> $r $blk
                key(a).cmp(&key(b))
            }
        })*
    );
}

macro_rules! def_order_by {
    (   $name:ident;
        ($a:ident, $b:ident) $cmp:block
        $( ($($generic:tt)*) $t:ty ;)*
    ) => {
        #[derive(Debug, Clone, Copy)]
        struct $name;

        $(
            impl<$($generic)*> $crate::SortOrder<$t> for $name
            {
                fn cmp($a: &$t, $b: &$t) -> $crate::macro_sort_order::Ordering {
                    $cmp
                }
            }
        )*
    }
}

def_order_by!{ Key0AscOrder;
    (a, b) { a.0.cmp(&b.0) }
    (K: Ord + Copy, T0) (K, T0);
    (K: Ord + Copy, T0, T1) (K, T0, T1);
    (K: Ord + Copy, T0, T1, T2) (K, T0, T1, T2);
    (K: Ord + Copy, T0, T1, T2, T3) (K, T0, T1, T2, T3);
    (K: Ord + Copy, T0, T1, T2, T3, T4) (K, T0, T1, T2, T3, T4);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5) (K, T0, T1, T2, T3, T4, T5);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6) (K, T0, T1, T2, T3, T4, T5, T6);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7) (K, T0, T1, T2, T3, T4, T5, T6, T7);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8) (K, T0, T1, T2, T3, T4, T5, T6, T7, T8);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (K, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (K, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) (K, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
}

def_order_by!{ Key1AscOrder;
    (a, b) { a.1.cmp(&b.1) }
    (K: Ord + Copy, T0) (T0, K);
    (K: Ord + Copy, T0, T1) (T0, K, T1);
    (K: Ord + Copy, T0, T1, T2) (T0, K, T1, T2);
    (K: Ord + Copy, T0, T1, T2, T3) (T0, K, T1, T2, T3);
    (K: Ord + Copy, T0, T1, T2, T3, T4) (T0, K, T1, T2, T3, T4);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5) (T0, K, T1, T2, T3, T4, T5);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6) (T0, K, T1, T2, T3, T4, T5, T6);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7) (T0, K, T1, T2, T3, T4, T5, T6, T7);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8) (T0, K, T1, T2, T3, T4, T5, T6, T7, T8);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (T0, K, T1, T2, T3, T4, T5, T6, T7, T8, T9);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (T0, K, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) (T0, K, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
}

def_order_by!{ Key2AscOrder;
    (a, b) { a.2.cmp(&b.2) }
    (K: Ord + Copy, T0, T1) (T0, T1, K);
    (K: Ord + Copy, T0, T1, T2) (T0, T1, K, T2);
    (K: Ord + Copy, T0, T1, T2, T3) (T0, T1, K, T2, T3);
    (K: Ord + Copy, T0, T1, T2, T3, T4) (T0, T1, K, T2, T3, T4);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5) (T0, T1, K, T2, T3, T4, T5);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6) (T0, T1, K, T2, T3, T4, T5, T6);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7) (T0, T1, K, T2, T3, T4, T5, T6, T7);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8) (T0, T1, K, T2, T3, T4, T5, T6, T7, T8);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (T0, T1, K, T2, T3, T4, T5, T6, T7, T8, T9);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (T0, T1, K, T2, T3, T4, T5, T6, T7, T8, T9, T10);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) (T0, T1, K, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
}

def_order_by!{ Key3AscOrder;
    (a, b) { a.3.cmp(&b.3) }
    (K: Ord + Copy, T0, T1, T2) (T0, T1, T2, K);
    (K: Ord + Copy, T0, T1, T2, T3) (T0, T1, T2, K, T3);
    (K: Ord + Copy, T0, T1, T2, T3, T4) (T0, T1, T2, K, T3, T4);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5) (T0, T1, T2, K, T3, T4, T5);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6) (T0, T1, T2, K, T3, T4, T5, T6);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7) (T0, T1, T2, K, T3, T4, T5, T6, T7);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8) (T0, T1, T2, K, T3, T4, T5, T6, T7, T8);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (T0, T1, T2, K, T3, T4, T5, T6, T7, T8, T9);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (T0, T1, T2, K, T3, T4, T5, T6, T7, T8, T9, T10);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) (T0, T1, T2, K, T3, T4, T5, T6, T7, T8, T9, T10, T11);
}

def_order_by!{ Key4AscOrder;
    (a, b) { a.4.cmp(&b.4) }
    (K: Ord + Copy, T0, T1, T2, T3) (T0, T1, T2, T3, K);
    (K: Ord + Copy, T0, T1, T2, T3, T4) (T0, T1, T2, T3, K, T4);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5) (T0, T1, T2, T3, K, T4, T5);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6) (T0, T1, T2, T3, K, T4, T5, T6);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7) (T0, T1, T2, T3, K, T4, T5, T6, T7);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8) (T0, T1, T2, T3, K, T4, T5, T6, T7, T8);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (T0, T1, T2, T3, K, T4, T5, T6, T7, T8, T9);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (T0, T1, T2, T3, K, T4, T5, T6, T7, T8, T9, T10);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) (T0, T1, T2, T3, K, T4, T5, T6, T7, T8, T9, T10, T11);
}

def_order_by!{ Key5AscOrder;
    (a, b) { a.5.cmp(&b.5) }
    (K: Ord + Copy, T0, T1, T2, T3, T4) (T0, T1, T2, T3, T4, K);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5) (T0, T1, T2, T3, T4, K, T5);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6) (T0, T1, T2, T3, T4, K, T5, T6);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7) (T0, T1, T2, T3, T4, K, T5, T6, T7);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8) (T0, T1, T2, T3, T4, K, T5, T6, T7, T8);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (T0, T1, T2, T3, T4, K, T5, T6, T7, T8, T9);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (T0, T1, T2, T3, T4, K, T5, T6, T7, T8, T9, T10);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) (T0, T1, T2, T3, T4, K, T5, T6, T7, T8, T9, T10, T11);
}

def_order_by!{ Key6AscOrder;
    (a, b) { a.6.cmp(&b.6) }
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5) (T0, T1, T2, T3, T4, T5, K);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6) (T0, T1, T2, T3, T4, T5, K, T6);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7) (T0, T1, T2, T3, T4, T5, K, T6, T7);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8) (T0, T1, T2, T3, T4, T5, K, T6, T7, T8);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (T0, T1, T2, T3, T4, T5, K, T6, T7, T8, T9);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (T0, T1, T2, T3, T4, T5, K, T6, T7, T8, T9, T10);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) (T0, T1, T2, T3, T4, T5, K, T6, T7, T8, T9, T10, T11);
}

def_order_by!{ Key7AscOrder;
    (a, b) { a.7.cmp(&b.7) }
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6) (T0, T1, T2, T3, T4, T5, T6, K);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7) (T0, T1, T2, T3, T4, T5, T6, K, T7);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8) (T0, T1, T2, T3, T4, T5, T6, K, T7, T8);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (T0, T1, T2, T3, T4, T5, T6, K, T7, T8, T9);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (T0, T1, T2, T3, T4, T5, T6, K, T7, T8, T9, T10);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) (T0, T1, T2, T3, T4, T5, T6, K, T7, T8, T9, T10, T11);
}

def_order_by!{ Key8AscOrder;
    (a, b) { a.8.cmp(&b.8) }
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7) (T0, T1, T2, T3, T4, T5, T6, T7, K);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8) (T0, T1, T2, T3, T4, T5, T6, T7, K, T8);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (T0, T1, T2, T3, T4, T5, T6, T7, K, T8, T9);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (T0, T1, T2, T3, T4, T5, T6, T7, K, T8, T9, T10);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) (T0, T1, T2, T3, T4, T5, T6, T7, K, T8, T9, T10, T11);
}

def_order_by!{ Key9AscOrder;
    (a, b) { a.9.cmp(&b.9) }
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8) (T0, T1, T2, T3, T4, T5, T6, T7, T8, K);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (T0, T1, T2, T3, T4, T5, T6, T7, T8, K, T9);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (T0, T1, T2, T3, T4, T5, T6, T7, T8, K, T9, T10);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) (T0, T1, T2, T3, T4, T5, T6, T7, T8, K, T9, T10, T11);
}

def_order_by!{ Key10AscOrder;
    (a, b) { a.10.cmp(&b.10) }
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, K);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, K, T10);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, K, T10, T11);
}

def_order_by!{ Key11AscOrder;
    (a, b) { a.11.cmp(&b.11) }
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, K);
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, K, T11);
}

def_order_by!{ Key12AscOrder;
    (a, b) { a.12.cmp(&b.12) }
    (K: Ord + Copy, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, K);
}<commit_msg>Removed old macro.<commit_after>pub use std::cmp::Ordering;

#[macro_export]
macro_rules! order_by_key {
    ($name:ident: $(fn ($($gen:tt)*) ($entry:ident: $t:ty) -> $r:ty $blk:block)*
    ) => (
        #[derive(Debug, Clone, Copy)]
        struct $name;

        $(impl<$($gen)*> $crate::SortOrder<$t> for $name
        {
            fn cmp(a: &$t, b: &$t) -> $crate::macro_sort_order::Ordering {
                fn key<$($gen)*>($entry: &$t) -> $r $blk
                key(a).cmp(&key(b))
            }
        })*
    );
}
<|endoftext|>


<commit_before>use dces::prelude::Entity;

use crate::{layout::*, render_object::*};

use super::BuildContext;

/// The `Template` trait defines the template for a particular type of a widget.
///
/// A widget's `Template` handles three type of objects:
/// * default property values, children, handlers
/// * a render object
/// * a layout object
pub trait Template: Sized {
    /// Builds the template of the widget and returns it.
    ///
    /// # Arguments
    /// * `_id`: The id (Entity) of the instantiated widget in the Entity Store
    /// * `_context`: The BuildContext used to build and instantiate new widgets
    ///
    /// # Example
    /// Define a widget called MyWidget with min, max and val properties with
    /// type of usize, and then set default values and add a TextBlock child.
    ///
    /// ```
    /// widget!(MyWidget {
    ///     min: usize,
    ///     max: usize,
    ///     val: usize
    /// });
    ///
    /// impl Template for MyWidget {
    ///     fn template(self, _id: Entity, context: &mut BuildContext) -> Self {
    ///         self.name("MyWidget")
    ///             .min(100)
    ///             .max(1000)
    ///             .val(500)
    ///             .child(TextBlock::new().text("Set a value!").build(context))
    ///     }
    ///
    ///     fn render_object(&self) -> Box<dyn RenderObject> {
    ///         Box::new(RectangleRenderObject)
    ///     }
    ///
    ///     fn layout(&self) -> Box<dyn Layout> {
    ///        Box::new(AbsoluteLayout)
    ///     }
    /// }
    /// ```
    fn template(self, _id: Entity, _ctx: &mut BuildContext) -> Self {
        self
    }

    /// Returns a pointer to a heap allocated object.
    ///
    /// `layout` takes care, how widget objects are arranged inside
    /// the canvas. This process will respect the given properties
    /// of the widget objects, that defines the contraints. For the list
    /// of available layout objects, see the [`render_object`] module.
    fn render_object(&self) -> Box<dyn RenderObject> {
        DefaultRenderObject.into()
    }

    /// Returns a pointer to a heap allocated object which specifies
    /// the way in which the widget are arranged or laid out on the
    /// canvas.  For the list of available layout objects, see the
    /// [`layout`] module.
    fn layout(&self) -> Box<dyn Layout> {
        GridLayout::new().into()
    }
}
<commit_msg>orbtk_core: update template documentation<commit_after>use dces::prelude::Entity;

use crate::{layout::*, render_object::*};

use super::BuildContext;

/// The `Template` trait is used to implement a particular widget type.
///
/// When a widget's `Template` is implemented, it provides three object types:
/// * a template objet (with default values for its properties, children, handlers)
/// * a render object
/// * a layout object
pub trait Template: Sized {
    /// Builds the template of the widget and returns it.
    ///
    /// # Arguments
    /// * `_id`: The id (Entity) of the instantiated widget in the Entity Store
    /// * `_context`: The BuildContext used to build and instantiate new widgets
    ///
    /// # Example
    /// Define a widget called MyWidget with min, max and val properties with
    /// type of usize, and then set default values and add a TextBlock child.
    ///
    /// ```
    /// widget!(MyWidget {
    ///     min: usize,
    ///     max: usize,
    ///     val: usize
    /// });
    ///
    /// impl Template for MyWidget {
    ///     fn template(self, _id: Entity, context: &mut BuildContext) -> Self {
    ///         self.name("MyWidget")
    ///             .min(100)
    ///             .max(1000)
    ///             .val(500)
    ///             .child(TextBlock::new().text("Set a value!").build(context))
    ///     }
    ///
    ///     fn render_object(&self) -> Box<dyn RenderObject> {
    ///         Box::new(RectangleRenderObject)
    ///     }
    ///
    ///     fn layout(&self) -> Box<dyn Layout> {
    ///        Box::new(AbsoluteLayout)
    ///     }
    /// }
    /// ```
    fn template(self, _id: Entity, _ctx: &mut BuildContext) -> Self {
        self
    }

    /// Returns a pointer to a heap allocated object.
    ///
    /// Widgets will be rendered as pixmaps inside the render buffer.
    /// For the list of available render objects, see the
    /// [`render_object`] module.
    ///
    /// [`render_object`]: ../../orbtk_core/render_object/index.html
    fn render_object(&self) -> Box<dyn RenderObject> {
        DefaultRenderObject.into()
    }

    /// Returns a pointer to a heap allocated object.
    ///
    /// The `layout` process will arrange all `box` entities of a widget
    /// in a tree, were size properties will meet the individual constraints.
    /// For the list of available layout objects, see
    /// the [`layout`] module.
    ///
    /// [`layout`]: ../../orbtk_core/layout/index.html
    fn layout(&self) -> Box<dyn Layout> {
        GridLayout::new().into()
    }
}
<|endoftext|>