<commit_before>pub use expectest::prelude::{be_ok, be_err};

pub use sql::parser::Node::{Table, TableColumn, Create, Insert, Values, Const};
pub use sql::parser::Type::{Int};
pub use sql::parser::Flag::{PrimeryKey, ForeignKey};
pub use sql::query_executer::QueryExecuter;

describe! database {

    before_each {
        let mut executer = QueryExecuter::default();
    }

    it "creates table with one column from AST" {
        let create_table = Create(Box::new(Table(table_name(), Some(vec![TableColumn(column_name(), Some(Int), None)]))));

        expect!(executer.execute(create_table)).to(be_ok().value(format!("'{}' was created", table_name())));
    }

    it "could not insert into table that does not exist" {
        let insert = Insert(Box::new(Table(table_name(), None)), Box::new(Values(vec![Const(ten_int())])));

        expect!(executer.execute(insert)).to(be_err().value(format!("[ERR 100] table '{}' does not exist", table_name())));
    }

    ignore "inserts row into table" {
        let create_table = Create(Box::new(Table(table_name(), Some(vec![TableColumn(column_name(), Some(Int), None)]))));

        expect!(executer.execute(create_table)).to(be_ok().value("".to_owned()));

        let insert = Insert(Box::new(Table(table_name(), None)), Box::new(Values(vec![Const(ten_int())])));

        expect!(executer.execute(insert)).to(be_ok().value("".to_owned()));
    }

    ignore "could not insert row with two columns in table with one column" {
        let create_table = Create(Box::new(Table(table_name(), Some(vec![TableColumn(column_name(), Some(Int), None)]))));

        expect!(executer.execute(create_table)).to(be_ok().value("".to_owned()));

        let insert = Insert(Box::new(Table(table_name(), None)), Box::new(Values(vec![Const(ten_int()), Const(five_int())])));

        expect!(executer.execute(insert)).to(be_err().value("".to_owned()));
    }

    ignore "creates tables with foreign key as reference" {
        let table = Create(Box::new(Table(table_name(), Some(vec![TableColumn(column_name(), Some(Int), Some(PrimeryKey))]))));

        expect!(executer.execute(table)).to(be_ok().value("".to_owned()));

        let reference_table = Create(Box::new(Table("reference_table".to_owned(), Some(vec![TableColumn(column_name(), Some(Int), Some(ForeignKey("table_name.col".to_owned())))]))));

        expect!(executer.execute(reference_table)).to(be_ok().value("".to_owned()));
    }

    ignore "could not insert into referencing table" {
        let table = Create(Box::new(Table(table_name(), Some(vec![TableColumn(column_name(), Some(Int), Some(PrimeryKey))]))));

        expect!(executer.execute(table)).to(be_ok().value("".to_owned()));

        let reference_table = Create(Box::new(Table("reference_table".to_owned(), Some(vec![TableColumn(column_name(), Some(Int), Some(ForeignKey("table_name.col".to_owned())))]))));

        expect!(executer.execute(reference_table)).to(be_ok());

        let insert = Insert(
            Box::new(Table("reference_table".to_owned(), None)),
            Box::new(Values(vec![Const(ten_int())]))
        );

        expect!(executer.execute(insert)).to(be_err().value("".to_owned()));
    }
}

pub fn table_name() -> String {
    "table_name".to_owned()
}

pub fn ten_int() -> String {
    "10".to_owned()
}

pub fn five_int() -> String {
    "5".to_owned()
}

pub fn column_name() -> String {
    "column_name".to_owned()
}
<commit_msg>remove unnecessary tests<commit_after>pub use expectest::prelude::{be_ok, be_err};

pub use sql::parser::Node::{Table, TableColumn, Create, Insert, Values, Const};
pub use sql::parser::Type::{Int};
pub use sql::parser::Flag::{PrimeryKey, ForeignKey};
pub use sql::query_executer::QueryExecuter;

describe! database {

    before_each {
        let mut executer = QueryExecuter::default();
    }

    it "creates table with one column from AST" {
        let create_table = Create(Box::new(Table(table_name(), Some(vec![TableColumn(column_name(), Some(Int), None)]))));

        expect!(executer.execute(create_table)).to(be_ok().value(format!("'{}' was created", table_name())));
    }

    it "could not insert into table that does not exist" {
        let insert = Insert(Box::new(Table(table_name(), None)), Box::new(Values(vec![Const(ten_int())])));

        expect!(executer.execute(insert)).to(be_err().value(format!("[ERR 100] table '{}' does not exist", table_name())));
    }
}

pub fn table_name() -> String {
    "table_name".to_owned()
}

pub fn ten_int() -> String {
    "10".to_owned()
}

pub fn five_int() -> String {
    "5".to_owned()
}

pub fn column_name() -> String {
    "column_name".to_owned()
}
<|endoftext|>


<commit_before>use crate::err::{self, Result};
use crate::series::local::Episode;
use crate::series::remote::SeriesInfo;
use lazy_static::lazy_static;
use regex::Regex;
use snafu::{OptionExt, ResultExt};
use std::f32;
use std::fs;
use std::path::{Path, PathBuf};

pub fn best_matching_title<S, I>(name: S, titles: I) -> Option<usize>
where
    S: AsRef<str>,
    I: IntoIterator<Item = String>,
{
    const MIN_CONFIDENCE: f32 = 0.6;

    let name = name.as_ref();

    let mut max_score = 0.0;
    let mut title_idx = None;

    for (i, title) in titles.into_iter().enumerate() {
        let title = match parse_title(title) {
            Some(mut title) => {
                title.make_ascii_lowercase();
                title
            }
            None => continue,
        };

        let score = strsim::jaro_winkler(&title, name) as f32;

        if score > max_score {
            if score >= 0.99 {
                return Some(i);
            }

            title_idx = Some(i);
            max_score = score;
        }
    }

    if max_score < MIN_CONFIDENCE {
        return None;
    }

    title_idx
}

pub fn best_matching_folder<S, P>(name: S, dir: P) -> Result<PathBuf>
where
    S: AsRef<str>,
    P: AsRef<Path>,
{
    let dir = dir.as_ref();
    let entries = fs::read_dir(dir).context(err::FileIO { path: dir })?;

    let mut dirs = Vec::new();

    for entry in entries {
        let entry = entry.context(err::EntryIO { dir })?;
        let etype = entry.file_type().context(err::EntryIO { dir })?;

        if !etype.is_dir() {
            continue;
        }

        dirs.push(entry);
    }

    let name = name.as_ref();

    let filenames = dirs
        .iter()
        .map(|name| name.file_name().to_string_lossy().into_owned());

    let dir_idx = best_matching_title(name, filenames).context(err::NoMatchingSeries { name })?;
    let dir = dirs.swap_remove(dir_idx);

    Ok(dir.path())
}

pub fn best_matching_info<S>(name: S, items: &[SeriesInfo]) -> Option<usize>
where
    S: AsRef<str>,
{
    // TODO: avoid cloning?
    let items = items
        .iter()
        .map(|info| info.title.clone())
        .collect::<Vec<_>>();

    best_matching_title(name, items)
}

pub fn parse_title<S>(item: S) -> Option<String>
where
    S: AsRef<str>,
{
    lazy_static! {
        // This pattern parses titles out of strings like this:
        // [GroupName] Series Title (01-13) [1080p]
        static ref EXTRACT_SERIES_TITLE: Regex =
            Regex::new(r"(?:\[.+?\]\s*)?(?P<title>.+?)(?:\(|\[|$)").unwrap();
    }

    let caps = EXTRACT_SERIES_TITLE.captures(item.as_ref())?;
    let title = Episode::clean_title(&caps["title"]);

    Some(title)
}
<commit_msg>[series] Improve automatic title detection<commit_after>use crate::err::{self, Result};
use crate::series::local::Episode;
use crate::series::remote::SeriesInfo;
use lazy_static::lazy_static;
use regex::Regex;
use snafu::{OptionExt, ResultExt};
use std::f32;
use std::fs;
use std::path::{Path, PathBuf};

pub fn best_matching_title<S, I>(name: S, titles: I) -> Option<usize>
where
    S: Into<String>,
    I: IntoIterator<Item = String>,
{
    const MIN_CONFIDENCE: f32 = 0.6;

    let name = {
        let mut name = name.into();
        name.make_ascii_lowercase();
        name
    };

    let mut max_score = 0.0;
    let mut title_idx = None;

    for (i, title) in titles.into_iter().enumerate() {
        let title = match parse_title(title) {
            Some(mut title) => {
                title.make_ascii_lowercase();
                title
            }
            None => continue,
        };

        let score = strsim::jaro(&title, &name) as f32;

        if score > max_score {
            if score >= 0.99 {
                return Some(i);
            }

            title_idx = Some(i);
            max_score = score;
        }
    }

    if max_score < MIN_CONFIDENCE {
        return None;
    }

    title_idx
}

pub fn best_matching_folder<S, P>(name: S, dir: P) -> Result<PathBuf>
where
    S: AsRef<str>,
    P: AsRef<Path>,
{
    let dir = dir.as_ref();
    let entries = fs::read_dir(dir).context(err::FileIO { path: dir })?;

    let mut dirs = Vec::new();

    for entry in entries {
        let entry = entry.context(err::EntryIO { dir })?;
        let etype = entry.file_type().context(err::EntryIO { dir })?;

        if !etype.is_dir() {
            continue;
        }

        dirs.push(entry);
    }

    let name = name.as_ref();

    let filenames = dirs
        .iter()
        .map(|name| name.file_name().to_string_lossy().into_owned());

    let dir_idx = best_matching_title(name, filenames).context(err::NoMatchingSeries { name })?;
    let dir = dirs.swap_remove(dir_idx);

    Ok(dir.path())
}

pub fn best_matching_info<S>(name: S, items: &[SeriesInfo]) -> Option<usize>
where
    S: Into<String>,
{
    // TODO: avoid cloning?
    let items = items
        .iter()
        .map(|info| info.title.clone())
        .collect::<Vec<_>>();

    best_matching_title(name, items)
}

pub fn parse_title<S>(item: S) -> Option<String>
where
    S: AsRef<str>,
{
    lazy_static! {
        // This pattern parses titles out of strings like this:
        // [GroupName] Series Title (01-13) [1080p]
        static ref EXTRACT_SERIES_TITLE: Regex =
            Regex::new(r"(?:\[.+?\]\s*)?(?P<title>.+?)(?:\(|\[|$)").unwrap();
    }

    let caps = EXTRACT_SERIES_TITLE.captures(item.as_ref())?;
    let title = Episode::clean_title(&caps["title"]);

    Some(title)
}
<|endoftext|>


<commit_before>extern crate mio;
extern crate rand;

use mio::{EventLoop,Token,TryWrite, Interest, PollOpt};
use mio::tcp::*;
use mio::udp::*;
use mio::buf::*;
use rand::{thread_rng, Rng};
use std::fs::File;
use std::io::*;

trait QuoteProviderImpl {
  fn get_quote(&self, usize) -> String;
  fn get_random_quote(&self) -> String;
  fn new() -> Self;
}

struct QuoteProvider {
  quotes: Vec<String>,
}

impl QuoteProviderImpl for QuoteProvider {

  fn get_quote(&self, index: usize) -> String {
    //todo: pointers not clones?
    self.quotes[index].clone()
  }

  fn get_random_quote(&self) -> String {
    //todo: cache rng for improved perf
    let mut rng = thread_rng();
    let index: usize = rng.gen_range(0, self.quotes.len());
    self.get_quote(index)
  }

  fn new() -> QuoteProvider {
    let mut quotes: Vec<String> = Vec::new();
    println!("Reading wisdom...");
    //todo: check exists
    //todo: pass in as arg
    let path = "../../src/server/wisdom.txt";
    let result = File::open(path);
    match result {
        Ok(file) => {
            let reader = BufReader::new(file);
            for line in reader.lines() {
                match line {
                    Ok (line_str) => {
                        if line_str.len() > 0 {
                            quotes.push(line_str + "\n");
                        } else {
                            println!("Skipped blank line in file.");
                        }
                    },
                    Err(e) => println!("Invalid line. Skipping... {:?}",e)
                }
            }

        },
        Err(e) => println!("Failed to open wisdom file {:?}. {:?}", path, e)
    }

    QuoteProvider {quotes: quotes}
  }
}

const TCP_SERVER: mio::Token = mio::Token(0);
const UDP_SERVER: mio::Token = mio::Token(1);

struct QotdServer {
    tcp_server: TcpListener,
    udp_server: UdpSocket,
    quote_provider: QuoteProvider
}

impl QotdServer {
    fn accept_tcp_connection(quote_provider: &QuoteProvider, tcp_listener: &TcpListener) {

        let stream_result = tcp_listener.accept();
        match stream_result {
            Ok(Some(mut connection)) => {
                println!("accepted a socket {:?}", connection);
                let quote = quote_provider.get_random_quote();
                //try!(connection.write_slice(quote.as_bytes()));
                let r = connection.write_slice(quote.as_bytes()) ;
                QotdServer::log_socket_write(r);
                drop(connection);
            }
            Ok(None) => {
                println!("the server socket wasn't actually ready")
            }
            Err(e) => {
                println!("listener.accept() errored: {}", e);
            }
        }
    }

    fn accept_udp_connection(quote_provider: &QuoteProvider, udp_socket: &UdpSocket) {
        println!("the server socket is ready to accept a UDP connection");
        let mut buf = [0; 128];
        match udp_socket.recv_from(&mut MutSliceBuf::wrap(&mut buf)) {
            Ok(Some(addr)) => {
                let quote = quote_provider.get_random_quote();
                let mut quote_buf = SliceBuf::wrap(&mut quote.as_bytes());
                let r = udp_socket.send_to(&mut quote_buf, &addr);
                QotdServer::log_socket_write(r);
            }
            Ok(None) => println!("Couldn't write to socket? Or was it just empty?"),
            Err(e) => println!("couldn't receive a datagram: {}", e)
        }
    }

    fn log_socket_write<T>(result: Result<Option<T>>) where T: std::fmt::Debug {
        match result {
            Ok(Some(bytes)) => println!("Wrote {:?} bytes to socket ", bytes),
            Ok(None) => println!("Didn't write any bytes"),
            Err(e) => println!("Failed to write. {:?}", e)
        }
    }
}

impl mio::Handler for QotdServer {
    type Timeout = ();
    type Message = ();

    #[allow(unused_variables)]
    fn readable(&mut self, event_loop: &mut mio::EventLoop<QotdServer>, token: mio::Token, hint: mio::ReadHint) {
        match token {
            TCP_SERVER => QotdServer::accept_tcp_connection(&self.quote_provider, &self.tcp_server),
            UDP_SERVER => QotdServer::accept_udp_connection(&self.quote_provider, &self.udp_server),
            _ => panic!("Received unknown token"),
        }
    }
}

macro_rules! vecxx {
    ( $( $x:expr ),* ) => {
        {
            let mut temp_vec = Vec::new();
            $(
                temp_vec.push($x);
            )*
            temp_vec
        }
    };
}

fn main() {

    let quote_provider: QuoteProvider = QuoteProviderImpl::new();
    println!("Sample quote: {:?}", quote_provider.get_random_quote());

    let address = "0.0.0.0:6567".parse().unwrap();
    let tcp_server = TcpListener::bind(&address).unwrap();
    let udp_server = UdpSocket::v4().unwrap();
    let _ = udp_server.bind(&address);

    let mut event_loop = mio::EventLoop::new().unwrap();
    let _ = event_loop.register_opt(&tcp_server, TCP_SERVER, Interest::readable(), PollOpt::edge());
    let _ = event_loop.register_opt(&udp_server, UDP_SERVER, Interest::readable(), PollOpt::edge());

    println!("running qotd server");
    let mut qotd_server = QotdServer
    {
        tcp_server: tcp_server,
        udp_server: udp_server,
        quote_provider: quote_provider
    };
    let _ = event_loop.run(&mut qotd_server);

    drop(qotd_server.udp_server);
    drop(qotd_server.tcp_server);

}<commit_msg>experimenting with macro for miotry<commit_after>extern crate mio;
extern crate rand;

use mio::{EventLoop,Token,TryWrite, Interest, PollOpt};
use mio::tcp::*;
use mio::udp::*;
use mio::buf::*;
use rand::{thread_rng, Rng};
use std::fs::File;
use std::io::*;

#[macro_export]
macro_rules! mytry {
    ($e:expr) => ({
        use ::std::result::Result::{Ok, Err};

        match $e {
            Ok(e) => e,
            Err(e) => return Err(e),
        }
    })
}

trait QuoteProviderImpl {
  fn get_quote(&self, usize) -> String;
  fn get_random_quote(&self) -> String;
  fn new() -> Self;
}

struct QuoteProvider {
  quotes: Vec<String>,
}

impl QuoteProviderImpl for QuoteProvider {

  fn get_quote(&self, index: usize) -> String {
    //todo: pointers not clones?
    self.quotes[index].clone()
  }

  fn get_random_quote(&self) -> String {
    //todo: cache rng for improved perf
    let mut rng = thread_rng();
    let index: usize = rng.gen_range(0, self.quotes.len());
    self.get_quote(index)
  }

  fn new() -> QuoteProvider {
    let mut quotes: Vec<String> = Vec::new();
    println!("Reading wisdom...");
    //todo: check exists
    //todo: pass in as arg
    let path = "../../src/server/wisdom.txt";
    let result = File::open(path);
    match result {
        Ok(file) => {
            let reader = BufReader::new(file);
            for line in reader.lines() {
                match line {
                    Ok (line_str) => {
                        if line_str.len() > 0 {
                            quotes.push(line_str + "\n");
                        } else {
                            println!("Skipped blank line in file.");
                        }
                    },
                    Err(e) => println!("Invalid line. Skipping... {:?}",e)
                }
            }

        },
        Err(e) => println!("Failed to open wisdom file {:?}. {:?}", path, e)
    }

    QuoteProvider {quotes: quotes}
  }
}

const TCP_SERVER: mio::Token = mio::Token(0);
const UDP_SERVER: mio::Token = mio::Token(1);

struct QotdServer {
    tcp_server: TcpListener,
    udp_server: UdpSocket,
    quote_provider: QuoteProvider
}

impl QotdServer {

    fn accept_tcp_connection(quote_provider: &QuoteProvider, tcp_listener: &TcpListener) {

        let stream_result = tcp_listener.accept();
        match stream_result {
            Ok(Some(mut connection)) => {
                println!("accepted a socket {:?}", connection);
                let result = connection.write_slice(quote_provider.get_random_quote().as_bytes()) ;
                QotdServer::log_socket_write(result);
                drop(connection);
            }
            Ok(None) => println!("The tcp socket wasn't actually ready"),
            Err(e) => println!("listener.accept() errored: {:?}", e)
        }
    }

    fn accept_udp_connection(quote_provider: &QuoteProvider, udp_socket: &UdpSocket) {
        println!("the server socket is ready to accept a UDP connection");
        let mut buf = [0; 128];
        match udp_socket.recv_from(&mut MutSliceBuf::wrap(&mut buf)) {
            Ok(Some(addr)) => {
                let quote = quote_provider.get_random_quote();
                let mut quote_buf = SliceBuf::wrap(&mut quote.as_bytes());
                let result = udp_socket.send_to(&mut quote_buf, &addr);
                QotdServer::log_socket_write(result);
            }
            Ok(None) => println!("The udp socket wasn't actually ready"),
            Err(e) => println!("couldn't receive a datagram: {}", e)
        }
    }

    fn log_socket_write<T>(result: Result<Option<T>>) where T: std::fmt::Debug {
        match result {
            Ok(Some(bytes)) => println!("Wrote {:?} bytes to socket ", bytes),
            Ok(None) => println!("Didn't write any bytes"),
            Err(e) => println!("Failed to write. {:?}", e)
        }
    }
}

impl mio::Handler for QotdServer {
    type Timeout = ();
    type Message = ();

    #[allow(unused_variables)]
    fn readable(&mut self, event_loop: &mut mio::EventLoop<QotdServer>, token: mio::Token, hint: mio::ReadHint) {
        match token {
            TCP_SERVER => QotdServer::accept_tcp_connection(&self.quote_provider, &self.tcp_server),
            UDP_SERVER => QotdServer::accept_udp_connection(&self.quote_provider, &self.udp_server),
            _ => panic!("Received unknown token"),
        }
    }
}

fn main() {

    let quote_provider: QuoteProvider = QuoteProviderImpl::new();
    println!("Sample quote: {:?}", quote_provider.get_random_quote());

    let address = "0.0.0.0:6567".parse().unwrap();
    let tcp_server = TcpListener::bind(&address).unwrap();
    let udp_server = UdpSocket::v4().unwrap();
    let _ = udp_server.bind(&address);

    let mut event_loop = mio::EventLoop::new().unwrap();
    let _ = event_loop.register_opt(&tcp_server, TCP_SERVER, Interest::readable(), PollOpt::edge());
    let _ = event_loop.register_opt(&udp_server, UDP_SERVER, Interest::readable(), PollOpt::edge());

    println!("running qotd server");
    let mut qotd_server = QotdServer
    {
        tcp_server: tcp_server,
        udp_server: udp_server,
        quote_provider: quote_provider
    };
    let _ = event_loop.run(&mut qotd_server);

    drop(qotd_server.udp_server);
    drop(qotd_server.tcp_server);

}<|endoftext|>


<commit_before>use ::bot::{Bot, Node, RoomEvent};

pub struct Echo<'a> {
    children: Vec<&'a str>
}

impl<'a> Echo<'a> {
    pub fn new() -> Self {
        Self {
            children: Vec::new()
        }
    }
}

impl<'a> Node<'a> for Echo<'a> {
    fn children(&self) -> Option<&Vec<&'a str>> {
        Some(&self.children)
    }

    fn register_child(&mut self, name: &'a str) {
        self.children.push(name);
    }

    fn handle(&mut self, bot: &Bot, event: RoomEvent) {
        let r = "!tEQUhDXnBDAeqCAgJk:cclub.cs.wmich.edu";
        let revent = event.raw_event;

        if revent.type_ == "m.room.message" && revent.content["msgtype"] == "m.text" {
            let body = &revent.content["body"].as_str().unwrap();
            let sender = &revent.sender;
            if body.starts_with("echo ") {
                bot.reply(&event, "HEY I'M MR. MESEEKS LOOK AT ME!");
            }

            println!("<{}> | {}", sender, body);
        }

        self.propagate_event(bot, event);
    }
}
<commit_msg>Echo service now uses reply and echos for real<commit_after>use ::bot::{Bot, Node, RoomEvent};

pub struct Echo<'a> {
    children: Vec<&'a str>
}

impl<'a> Echo<'a> {
    pub fn new() -> Self {
        Self {
            children: Vec::new()
        }
    }
}

impl<'a> Node<'a> for Echo<'a> {
    fn children(&self) -> Option<&Vec<&'a str>> {
        Some(&self.children)
    }

    fn register_child(&mut self, name: &'a str) {
        self.children.push(name);
    }

    fn handle(&mut self, bot: &Bot, event: RoomEvent) {
        let revent = event.raw_event;

        if revent.type_ == "m.room.message" && revent.content["msgtype"] == "m.text" {
            let body = &revent.content["body"].as_str().unwrap();
            let sender = &revent.sender;
            if body.starts_with("echo ") {
                bot.reply(&event, &body[5..]);
            }

            println!("<{}> | {}", sender, body);
        }

        self.propagate_event(bot, event);
    }
}
<|endoftext|>


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

use std::collections::HashMap;
use std::sync::Arc;

use intern::string_key::StringKey;
use intern::string_key::StringKeyMap;
use schema::SDLSchema;

use crate::ir::ExecutableDefinition;
use crate::ir::FragmentDefinition;
use crate::ir::FragmentDefinitionName;
use crate::ir::FragmentDefinitionNameMap;
use crate::ir::OperationDefinition;
use crate::ir::OperationDefinitionName;

/// A collection of all documents that are being compiled.
#[derive(Debug, Clone)]
pub struct Program {
    pub schema: Arc<SDLSchema>,
    pub fragments: FragmentDefinitionNameMap<Arc<FragmentDefinition>>,
    pub operations: Vec<Arc<OperationDefinition>>,
}

impl Program {
    pub fn new(schema: Arc<SDLSchema>) -> Self {
        Self {
            schema,
            fragments: Default::default(),
            operations: Default::default(),
        }
    }

    pub fn from_definitions(
        schema: Arc<SDLSchema>,
        definitions: Vec<ExecutableDefinition>,
    ) -> Self {
        let mut operations = Vec::new();
        let mut fragments = HashMap::default();
        for definition in definitions {
            match definition {
                ExecutableDefinition::Operation(operation) => {
                    operations.push(Arc::new(operation));
                }
                ExecutableDefinition::Fragment(fragment) => {
                    fragments.insert(fragment.name.item, Arc::new(fragment));
                }
            }
        }
        Self {
            schema,
            fragments,
            operations,
        }
    }

    pub fn insert_fragment(&mut self, fragment: Arc<FragmentDefinition>) {
        let name = fragment.name.item;
        if let Some(previous) = self.fragments.insert(name, fragment) {
            panic!(
                "Can only insert '{}' once. Had {:?} and trying to insert {:?}.",
                name, previous, self.fragments[&name]
            );
        };
    }

    pub fn fragment(&self, name: FragmentDefinitionName) -> Option<&Arc<FragmentDefinition>> {
        self.fragments.get(&name)
    }

    pub fn fragment_mut(
        &mut self,
        name: FragmentDefinitionName,
    ) -> Option<&mut Arc<FragmentDefinition>> {
        self.fragments.get_mut(&name)
    }

    /// Searches for an operation by name.
    ///
    /// NOTE: This is a linear search, we currently don't frequently search
    ///       for operations by name, so this might be overall faster than
    ///       using a map internally.
    pub fn operation(&self, name: OperationDefinitionName) -> Option<&Arc<OperationDefinition>> {
        self.operations()
            .find(|operation| operation.name.item == name)
    }

    pub fn insert_operation(&mut self, operation: Arc<OperationDefinition>) {
        self.operations.push(operation);
    }

    pub fn operations(&self) -> impl Iterator<Item = &Arc<OperationDefinition>> {
        self.operations.iter()
    }

    pub fn fragments(&self) -> impl Iterator<Item = &Arc<FragmentDefinition>> {
        self.fragments.values()
    }

    pub fn document_count(&self) -> usize {
        self.fragments.len() + self.operations.len()
    }

    pub fn merge_program(
        &mut self,
        other_program: &Self,
        removed_definition_names: Option<&[StringKey]>,
    ) {
        let mut operations: StringKeyMap<Arc<OperationDefinition>> = self
            .operations
            .drain(..)
            .map(|op| (op.name.item.0, op))
            .collect();
        for fragment in other_program.fragments() {
            self.fragments
                .insert(fragment.name.item, Arc::clone(fragment));
        }
        for operation in other_program.operations() {
            operations.insert(operation.name.item.0, Arc::clone(operation));
        }
        if let Some(removed_definition_names) = removed_definition_names {
            for removed in removed_definition_names {
                self.fragments.remove(&FragmentDefinitionName(*removed));
                operations.remove(removed);
            }
        }
        self.operations
            .extend(operations.into_iter().map(|(_, op)| op));
    }
}
<commit_msg>Disallow duplicate fragments when getting program<commit_after>/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

use std::collections::HashMap;
use std::sync::Arc;

use intern::string_key::StringKey;
use intern::string_key::StringKeyMap;
use schema::SDLSchema;

use crate::ir::ExecutableDefinition;
use crate::ir::FragmentDefinition;
use crate::ir::FragmentDefinitionName;
use crate::ir::FragmentDefinitionNameMap;
use crate::ir::OperationDefinition;
use crate::ir::OperationDefinitionName;

/// A collection of all documents that are being compiled.
#[derive(Debug, Clone)]
pub struct Program {
    pub schema: Arc<SDLSchema>,
    pub fragments: FragmentDefinitionNameMap<Arc<FragmentDefinition>>,
    pub operations: Vec<Arc<OperationDefinition>>,
}

impl Program {
    pub fn new(schema: Arc<SDLSchema>) -> Self {
        Self {
            schema,
            fragments: Default::default(),
            operations: Default::default(),
        }
    }

    pub fn from_definitions(
        schema: Arc<SDLSchema>,
        definitions: Vec<ExecutableDefinition>,
    ) -> Self {
        let mut operations = Vec::new();
        let mut fragments = HashMap::default();
        let mut seen_operation_loc = HashMap::new();
        for definition in definitions {
            match definition {
                ExecutableDefinition::Operation(operation) => {
                    let loc = operation.name.location;
                    let name = operation.name.item;
                    if let Some(another) = seen_operation_loc.insert(name, loc) {
                        panic!(
                            "\nDuplicate operation definitions named {}: \nfirst one: {:?}\nsecond one: {:?}\n",
                            name, loc, another
                        );
                    }
                    operations.push(Arc::new(operation)); // Keep the order the operations same as inputs.
                }
                ExecutableDefinition::Fragment(fragment) => {
                    let loc = fragment.name.location;
                    let name = fragment.name.item;
                    if let Some(another) = fragments.insert(name, Arc::new(fragment)) {
                        panic!(
                            "\nDuplicate fragment definitions named {}: \nfirst one: {:?}\nsecond one: {:?}\n",
                            name, loc, &another.name.location
                        );
                    }
                }
            }
        }
        Self {
            schema,
            fragments,
            operations,
        }
    }

    pub fn insert_fragment(&mut self, fragment: Arc<FragmentDefinition>) {
        let name = fragment.name.item;
        if let Some(previous) = self.fragments.insert(name, fragment) {
            panic!(
                "Can only insert '{}' once. Had {:?} and trying to insert {:?}.",
                name, previous, self.fragments[&name]
            );
        };
    }

    pub fn fragment(&self, name: FragmentDefinitionName) -> Option<&Arc<FragmentDefinition>> {
        self.fragments.get(&name)
    }

    pub fn fragment_mut(
        &mut self,
        name: FragmentDefinitionName,
    ) -> Option<&mut Arc<FragmentDefinition>> {
        self.fragments.get_mut(&name)
    }

    /// Searches for an operation by name.
    ///
    /// NOTE: This is a linear search, we currently don't frequently search
    ///       for operations by name, so this might be overall faster than
    ///       using a map internally.
    pub fn operation(&self, name: OperationDefinitionName) -> Option<&Arc<OperationDefinition>> {
        self.operations()
            .find(|operation| operation.name.item == name)
    }

    pub fn insert_operation(&mut self, operation: Arc<OperationDefinition>) {
        self.operations.push(operation);
    }

    pub fn operations(&self) -> impl Iterator<Item = &Arc<OperationDefinition>> {
        self.operations.iter()
    }

    pub fn fragments(&self) -> impl Iterator<Item = &Arc<FragmentDefinition>> {
        self.fragments.values()
    }

    pub fn document_count(&self) -> usize {
        self.fragments.len() + self.operations.len()
    }

    pub fn merge_program(
        &mut self,
        other_program: &Self,
        removed_definition_names: Option<&[StringKey]>,
    ) {
        let mut operations: StringKeyMap<Arc<OperationDefinition>> = self
            .operations
            .drain(..)
            .map(|op| (op.name.item.0, op))
            .collect();
        for fragment in other_program.fragments() {
            self.fragments
                .insert(fragment.name.item, Arc::clone(fragment));
        }
        for operation in other_program.operations() {
            operations.insert(operation.name.item.0, Arc::clone(operation));
        }
        if let Some(removed_definition_names) = removed_definition_names {
            for removed in removed_definition_names {
                self.fragments.remove(&FragmentDefinitionName(*removed));
                operations.remove(removed);
            }
        }
        self.operations
            .extend(operations.into_iter().map(|(_, op)| op));
    }
}
<|endoftext|>


<commit_before>use crate::ich::{self, StableHashingContext};
use crate::traits::specialization_graph;
use crate::ty::fast_reject;
use crate::ty::fold::TypeFoldable;
use crate::ty::{Ty, TyCtxt};
use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, DefId};
use rustc_hir::definitions::DefPathHash;
use rustc_hir::HirId;

use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_errors::ErrorReported;
use rustc_macros::HashStable;
use std::collections::BTreeMap;

/// A trait's definition with type information.
#[derive(HashStable)]
pub struct TraitDef {
    // We already have the def_path_hash below, no need to hash it twice
    #[stable_hasher(ignore)]
    pub def_id: DefId,

    pub unsafety: hir::Unsafety,

    /// If `true`, then this trait had the `#[rustc_paren_sugar]`
    /// attribute, indicating that it should be used with `Foo()`
    /// sugar. This is a temporary thing -- eventually any trait will
    /// be usable with the sugar (or without it).
    pub paren_sugar: bool,

    pub has_auto_impl: bool,

    /// If `true`, then this trait has the `#[marker]` attribute, indicating
    /// that all its associated items have defaults that cannot be overridden,
    /// and thus `impl`s of it are allowed to overlap.
    pub is_marker: bool,

    /// Used to determine whether the standard library is allowed to specialize
    /// on this trait.
    pub specialization_kind: TraitSpecializationKind,

    /// The ICH of this trait's DefPath, cached here so it doesn't have to be
    /// recomputed all the time.
    pub def_path_hash: DefPathHash,
}

/// Whether this trait is treated specially by the standard library
/// specialization lint.
#[derive(HashStable, PartialEq, Clone, Copy, TyEncodable, TyDecodable)]
pub enum TraitSpecializationKind {
    /// The default. Specializing on this trait is not allowed.
    None,
    /// Specializing on this trait is allowed because it doesn't have any
    /// methods. For example `Sized` or `FusedIterator`.
    /// Applies to traits with the `rustc_unsafe_specialization_marker`
    /// attribute.
    Marker,
    /// Specializing on this trait is allowed because all of the impls of this
    /// trait are "always applicable". Always applicable means that if
    /// `X<'x>: T<'y>` for any lifetimes, then `for<'a, 'b> X<'a>: T<'b>`.
    /// Applies to traits with the `rustc_specialization_trait` attribute.
    AlwaysApplicable,
}

#[derive(Default)]
pub struct TraitImpls {
    blanket_impls: Vec<DefId>,
    /// Impls indexed by their simplified self type, for fast lookup.
    non_blanket_impls: FxHashMap<fast_reject::SimplifiedType, Vec<DefId>>,
}

impl<'tcx> TraitDef {
    pub fn new(
        def_id: DefId,
        unsafety: hir::Unsafety,
        paren_sugar: bool,
        has_auto_impl: bool,
        is_marker: bool,
        specialization_kind: TraitSpecializationKind,
        def_path_hash: DefPathHash,
    ) -> TraitDef {
        TraitDef {
            def_id,
            unsafety,
            paren_sugar,
            has_auto_impl,
            is_marker,
            specialization_kind,
            def_path_hash,
        }
    }

    pub fn ancestors(
        &self,
        tcx: TyCtxt<'tcx>,
        of_impl: DefId,
    ) -> Result<specialization_graph::Ancestors<'tcx>, ErrorReported> {
        specialization_graph::ancestors(tcx, self.def_id, of_impl)
    }
}

impl<'tcx> TyCtxt<'tcx> {
    pub fn for_each_impl<F: FnMut(DefId)>(self, def_id: DefId, mut f: F) {
        let impls = self.trait_impls_of(def_id);

        for &impl_def_id in impls.blanket_impls.iter() {
            f(impl_def_id);
        }

        for v in impls.non_blanket_impls.values() {
            for &impl_def_id in v {
                f(impl_def_id);
            }
        }
    }

    /// Iterate over every impl that could possibly match the
    /// self type `self_ty`.
    pub fn for_each_relevant_impl<F: FnMut(DefId)>(
        self,
        def_id: DefId,
        self_ty: Ty<'tcx>,
        mut f: F,
    ) {
        let impls = self.trait_impls_of(def_id);

        for &impl_def_id in impls.blanket_impls.iter() {
            f(impl_def_id);
        }

        // simplify_type(.., false) basically replaces type parameters and
        // projections with infer-variables. This is, of course, done on
        // the impl trait-ref when it is instantiated, but not on the
        // predicate trait-ref which is passed here.
        //
        // for example, if we match `S: Copy` against an impl like
        // `impl<T:Copy> Copy for Option<T>`, we replace the type variable
        // in `Option<T>` with an infer variable, to `Option<_>` (this
        // doesn't actually change fast_reject output), but we don't
        // replace `S` with anything - this impl of course can't be
        // selected, and as there are hundreds of similar impls,
        // considering them would significantly harm performance.

        // This depends on the set of all impls for the trait. That is
        // unfortunate. When we get red-green recompilation, we would like
        // to have a way of knowing whether the set of relevant impls
        // changed. The most naive
        // way would be to compute the Vec of relevant impls and see whether
        // it differs between compilations. That shouldn't be too slow by
        // itself - we do quite a bit of work for each relevant impl anyway.
        //
        // If we want to be faster, we could have separate queries for
        // blanket and non-blanket impls, and compare them separately.
        //
        // I think we'll cross that bridge when we get to it.
        if let Some(simp) = fast_reject::simplify_type(self, self_ty, true) {
            if let Some(impls) = impls.non_blanket_impls.get(&simp) {
                for &impl_def_id in impls {
                    f(impl_def_id);
                }
            }
        } else {
            for &impl_def_id in impls.non_blanket_impls.values().flatten() {
                f(impl_def_id);
            }
        }
    }

    /// Returns a vector containing all impls
    pub fn all_impls(self, def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
        let TraitImpls { blanket_impls, non_blanket_impls } = self.trait_impls_of(def_id);

        blanket_impls.iter().chain(non_blanket_impls.iter().map(|(_, v)| v).flatten()).cloned()
    }
}

// Query provider for `all_local_trait_impls`.
pub(super) fn all_local_trait_impls<'tcx>(
    tcx: TyCtxt<'tcx>,
    krate: CrateNum,
) -> &'tcx BTreeMap<DefId, Vec<HirId>> {
    &tcx.hir_crate(krate).trait_impls
}

// Query provider for `trait_impls_of`.
pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> TraitImpls {
    let mut impls = TraitImpls::default();

    // Traits defined in the current crate can't have impls in upstream
    // crates, so we don't bother querying the cstore.
    if !trait_id.is_local() {
        for &cnum in tcx.crates().iter() {
            for &(impl_def_id, simplified_self_ty) in
                tcx.implementations_of_trait((cnum, trait_id)).iter()
            {
                if let Some(simplified_self_ty) = simplified_self_ty {
                    impls
                        .non_blanket_impls
                        .entry(simplified_self_ty)
                        .or_default()
                        .push(impl_def_id);
                } else {
                    impls.blanket_impls.push(impl_def_id);
                }
            }
        }
    }

    for &hir_id in tcx.hir().trait_impls(trait_id) {
        let impl_def_id = tcx.hir().local_def_id(hir_id).to_def_id();

        let impl_self_ty = tcx.type_of(impl_def_id);
        if impl_self_ty.references_error() {
            continue;
        }

        if let Some(simplified_self_ty) = fast_reject::simplify_type(tcx, impl_self_ty, false) {
            impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id);
        } else {
            impls.blanket_impls.push(impl_def_id);
        }
    }

    impls
}

impl<'a> HashStable<StableHashingContext<'a>> for TraitImpls {
    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
        let TraitImpls { ref blanket_impls, ref non_blanket_impls } = *self;

        ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, non_blanket_impls);
    }
}
<commit_msg>Rollup merge of #76403 - scileo:doc-all-impls, r=lcnr<commit_after>use crate::ich::{self, StableHashingContext};
use crate::traits::specialization_graph;
use crate::ty::fast_reject;
use crate::ty::fold::TypeFoldable;
use crate::ty::{Ty, TyCtxt};
use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, DefId};
use rustc_hir::definitions::DefPathHash;
use rustc_hir::HirId;

use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_errors::ErrorReported;
use rustc_macros::HashStable;
use std::collections::BTreeMap;

/// A trait's definition with type information.
#[derive(HashStable)]
pub struct TraitDef {
    // We already have the def_path_hash below, no need to hash it twice
    #[stable_hasher(ignore)]
    pub def_id: DefId,

    pub unsafety: hir::Unsafety,

    /// If `true`, then this trait had the `#[rustc_paren_sugar]`
    /// attribute, indicating that it should be used with `Foo()`
    /// sugar. This is a temporary thing -- eventually any trait will
    /// be usable with the sugar (or without it).
    pub paren_sugar: bool,

    pub has_auto_impl: bool,

    /// If `true`, then this trait has the `#[marker]` attribute, indicating
    /// that all its associated items have defaults that cannot be overridden,
    /// and thus `impl`s of it are allowed to overlap.
    pub is_marker: bool,

    /// Used to determine whether the standard library is allowed to specialize
    /// on this trait.
    pub specialization_kind: TraitSpecializationKind,

    /// The ICH of this trait's DefPath, cached here so it doesn't have to be
    /// recomputed all the time.
    pub def_path_hash: DefPathHash,
}

/// Whether this trait is treated specially by the standard library
/// specialization lint.
#[derive(HashStable, PartialEq, Clone, Copy, TyEncodable, TyDecodable)]
pub enum TraitSpecializationKind {
    /// The default. Specializing on this trait is not allowed.
    None,
    /// Specializing on this trait is allowed because it doesn't have any
    /// methods. For example `Sized` or `FusedIterator`.
    /// Applies to traits with the `rustc_unsafe_specialization_marker`
    /// attribute.
    Marker,
    /// Specializing on this trait is allowed because all of the impls of this
    /// trait are "always applicable". Always applicable means that if
    /// `X<'x>: T<'y>` for any lifetimes, then `for<'a, 'b> X<'a>: T<'b>`.
    /// Applies to traits with the `rustc_specialization_trait` attribute.
    AlwaysApplicable,
}

#[derive(Default)]
pub struct TraitImpls {
    blanket_impls: Vec<DefId>,
    /// Impls indexed by their simplified self type, for fast lookup.
    non_blanket_impls: FxHashMap<fast_reject::SimplifiedType, Vec<DefId>>,
}

impl<'tcx> TraitDef {
    pub fn new(
        def_id: DefId,
        unsafety: hir::Unsafety,
        paren_sugar: bool,
        has_auto_impl: bool,
        is_marker: bool,
        specialization_kind: TraitSpecializationKind,
        def_path_hash: DefPathHash,
    ) -> TraitDef {
        TraitDef {
            def_id,
            unsafety,
            paren_sugar,
            has_auto_impl,
            is_marker,
            specialization_kind,
            def_path_hash,
        }
    }

    pub fn ancestors(
        &self,
        tcx: TyCtxt<'tcx>,
        of_impl: DefId,
    ) -> Result<specialization_graph::Ancestors<'tcx>, ErrorReported> {
        specialization_graph::ancestors(tcx, self.def_id, of_impl)
    }
}

impl<'tcx> TyCtxt<'tcx> {
    pub fn for_each_impl<F: FnMut(DefId)>(self, def_id: DefId, mut f: F) {
        let impls = self.trait_impls_of(def_id);

        for &impl_def_id in impls.blanket_impls.iter() {
            f(impl_def_id);
        }

        for v in impls.non_blanket_impls.values() {
            for &impl_def_id in v {
                f(impl_def_id);
            }
        }
    }

    /// Iterate over every impl that could possibly match the
    /// self type `self_ty`.
    pub fn for_each_relevant_impl<F: FnMut(DefId)>(
        self,
        def_id: DefId,
        self_ty: Ty<'tcx>,
        mut f: F,
    ) {
        let impls = self.trait_impls_of(def_id);

        for &impl_def_id in impls.blanket_impls.iter() {
            f(impl_def_id);
        }

        // simplify_type(.., false) basically replaces type parameters and
        // projections with infer-variables. This is, of course, done on
        // the impl trait-ref when it is instantiated, but not on the
        // predicate trait-ref which is passed here.
        //
        // for example, if we match `S: Copy` against an impl like
        // `impl<T:Copy> Copy for Option<T>`, we replace the type variable
        // in `Option<T>` with an infer variable, to `Option<_>` (this
        // doesn't actually change fast_reject output), but we don't
        // replace `S` with anything - this impl of course can't be
        // selected, and as there are hundreds of similar impls,
        // considering them would significantly harm performance.

        // This depends on the set of all impls for the trait. That is
        // unfortunate. When we get red-green recompilation, we would like
        // to have a way of knowing whether the set of relevant impls
        // changed. The most naive
        // way would be to compute the Vec of relevant impls and see whether
        // it differs between compilations. That shouldn't be too slow by
        // itself - we do quite a bit of work for each relevant impl anyway.
        //
        // If we want to be faster, we could have separate queries for
        // blanket and non-blanket impls, and compare them separately.
        //
        // I think we'll cross that bridge when we get to it.
        if let Some(simp) = fast_reject::simplify_type(self, self_ty, true) {
            if let Some(impls) = impls.non_blanket_impls.get(&simp) {
                for &impl_def_id in impls {
                    f(impl_def_id);
                }
            }
        } else {
            for &impl_def_id in impls.non_blanket_impls.values().flatten() {
                f(impl_def_id);
            }
        }
    }

    /// Returns an iterator containing all impls
    pub fn all_impls(self, def_id: DefId) -> impl Iterator<Item = DefId> + 'tcx {
        let TraitImpls { blanket_impls, non_blanket_impls } = self.trait_impls_of(def_id);

        blanket_impls.iter().chain(non_blanket_impls.iter().map(|(_, v)| v).flatten()).cloned()
    }
}

// Query provider for `all_local_trait_impls`.
pub(super) fn all_local_trait_impls<'tcx>(
    tcx: TyCtxt<'tcx>,
    krate: CrateNum,
) -> &'tcx BTreeMap<DefId, Vec<HirId>> {
    &tcx.hir_crate(krate).trait_impls
}

// Query provider for `trait_impls_of`.
pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> TraitImpls {
    let mut impls = TraitImpls::default();

    // Traits defined in the current crate can't have impls in upstream
    // crates, so we don't bother querying the cstore.
    if !trait_id.is_local() {
        for &cnum in tcx.crates().iter() {
            for &(impl_def_id, simplified_self_ty) in
                tcx.implementations_of_trait((cnum, trait_id)).iter()
            {
                if let Some(simplified_self_ty) = simplified_self_ty {
                    impls
                        .non_blanket_impls
                        .entry(simplified_self_ty)
                        .or_default()
                        .push(impl_def_id);
                } else {
                    impls.blanket_impls.push(impl_def_id);
                }
            }
        }
    }

    for &hir_id in tcx.hir().trait_impls(trait_id) {
        let impl_def_id = tcx.hir().local_def_id(hir_id).to_def_id();

        let impl_self_ty = tcx.type_of(impl_def_id);
        if impl_self_ty.references_error() {
            continue;
        }

        if let Some(simplified_self_ty) = fast_reject::simplify_type(tcx, impl_self_ty, false) {
            impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id);
        } else {
            impls.blanket_impls.push(impl_def_id);
        }
    }

    impls
}

impl<'a> HashStable<StableHashingContext<'a>> for TraitImpls {
    fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
        let TraitImpls { ref blanket_impls, ref non_blanket_impls } = *self;

        ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, non_blanket_impls);
    }
}
<|endoftext|>


<commit_before>// The following definitions are correct for arm and i686,
// but may be wrong for mips

pub type c_long = i32;
pub type c_ulong = u32;
pub type mode_t = u16;
pub type off64_t = ::c_longlong;
pub type sigset_t = ::c_ulong;
pub type socklen_t = i32;
pub type time64_t = i64;

s! {
    pub struct sigaction {
        pub sa_sigaction: ::sighandler_t,
        pub sa_mask: ::sigset_t,
        pub sa_flags: ::c_ulong,
        pub sa_restorer: ::dox::Option<extern fn()>,
    }

    pub struct rlimit64 {
        pub rlim_cur: u64,
        pub rlim_max: u64,
    }

    pub struct stat {
        pub st_dev: ::c_ulonglong,
        __pad0: [::c_uchar; 4],
        __st_ino: ::ino_t,
        pub st_mode: ::c_uint,
        pub st_nlink: ::c_uint,
        pub st_uid: ::uid_t,
        pub st_gid: ::gid_t,
        pub st_rdev: ::c_ulonglong,
        __pad3: [::c_uchar; 4],
        pub st_size: ::c_longlong,
        pub st_blksize: ::blksize_t,
        pub st_blocks: ::c_ulonglong,
        pub st_atime: ::c_ulong,
        pub st_atime_nsec: ::c_ulong,
        pub st_mtime: ::c_ulong,
        pub st_mtime_nsec: ::c_ulong,
        pub st_ctime: ::c_ulong,
        pub st_ctime_nsec: ::c_ulong,
        pub st_ino: ::c_ulonglong,
    }

    pub struct stat64 {
        pub st_dev: ::c_ulonglong,
        __pad0: [::c_uchar; 4],
        __st_ino: ::ino_t,
        pub st_mode: ::c_uint,
        pub st_nlink: ::c_uint,
        pub st_uid: ::uid_t,
        pub st_gid: ::gid_t,
        pub st_rdev: ::c_ulonglong,
        __pad3: [::c_uchar; 4],
        pub st_size: ::c_longlong,
        pub st_blksize: ::blksize_t,
        pub st_blocks: ::c_ulonglong,
        pub st_atime: ::c_ulong,
        pub st_atime_nsec: ::c_ulong,
        pub st_mtime: ::c_ulong,
        pub st_mtime_nsec: ::c_ulong,
        pub st_ctime: ::c_ulong,
        pub st_ctime_nsec: ::c_ulong,
        pub st_ino: ::c_ulonglong,
    }

    pub struct pthread_attr_t {
        pub flags: ::uint32_t,
        pub stack_base: *mut ::c_void,
        pub stack_size: ::size_t,
        pub guard_size: ::size_t,
        pub sched_policy: ::int32_t,
        pub sched_priority: ::int32_t,
    }

    pub struct pthread_mutex_t { value: ::c_int }

    pub struct pthread_cond_t { value: ::c_int }

    pub struct pthread_rwlock_t {
        lock: pthread_mutex_t,
        cond: pthread_cond_t,
        numLocks: ::c_int,
        writerThreadId: ::c_int,
        pendingReaders: ::c_int,
        pendingWriters: ::c_int,
        attr: i32,
        __reserved: [::c_char; 12],
    }

    pub struct passwd {
        pub pw_name: *mut ::c_char,
        pub pw_passwd: *mut ::c_char,
        pub pw_uid: ::uid_t,
        pub pw_gid: ::gid_t,
        pub pw_dir: *mut ::c_char,
        pub pw_shell: *mut ::c_char,
    }

    pub struct statfs {
        pub f_type: ::uint32_t,
        pub f_bsize: ::uint32_t,
        pub f_blocks: ::uint64_t,
        pub f_bfree: ::uint64_t,
        pub f_bavail: ::uint64_t,
        pub f_files: ::uint64_t,
        pub f_ffree: ::uint64_t,
        pub f_fsid: ::__fsid_t,
        pub f_namelen: ::uint32_t,
        pub f_frsize: ::uint32_t,
        pub f_flags: ::uint32_t,
        pub f_spare: [::uint32_t; 4],
    }

    pub struct sysinfo {
        pub uptime: ::c_long,
        pub loads: [::c_ulong; 3],
        pub totalram: ::c_ulong,
        pub freeram: ::c_ulong,
        pub sharedram: ::c_ulong,
        pub bufferram: ::c_ulong,
        pub totalswap: ::c_ulong,
        pub freeswap: ::c_ulong,
        pub procs: ::c_ushort,
        pub pad: ::c_ushort,
        pub totalhigh: ::c_ulong,
        pub freehigh: ::c_ulong,
        pub mem_unit: ::c_uint,
        pub _f: [::c_char; 8],
    }
}

pub const RTLD_GLOBAL: ::c_int = 2;
pub const RTLD_NOW: ::c_int = 0;
pub const RTLD_DEFAULT: *mut ::c_void = -1isize as *mut ::c_void;

pub const PTRACE_GETFPREGS: ::c_int = 14;
pub const PTRACE_SETFPREGS: ::c_int = 15;
pub const PTRACE_GETREGS: ::c_int = 12;
pub const PTRACE_SETREGS: ::c_int = 13;

pub const SYS_gettid: ::c_long = 224;
pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
    value: 0,
};
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
    value: 0,
};
pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
    lock: PTHREAD_MUTEX_INITIALIZER,
    cond: PTHREAD_COND_INITIALIZER,
    numLocks: 0,
    writerThreadId: 0,
    pendingReaders: 0,
    pendingWriters: 0,
    attr: 0,
    __reserved: [0; 12],
};
pub const PTHREAD_STACK_MIN: ::size_t = 4096 * 2;
pub const CPU_SETSIZE: ::size_t = 32;
pub const __CPU_BITS: ::size_t = 32;

pub const UT_LINESIZE: usize = 8;
pub const UT_NAMESIZE: usize = 8;
pub const UT_HOSTSIZE: usize = 16;

pub const SIGSTKSZ: ::size_t = 8192;
pub const MINSIGSTKSZ: ::size_t = 2048;

extern {
    pub fn bind(socket: ::c_int, address: *const ::sockaddr,
                address_len: socklen_t) -> ::c_int;

    pub fn writev(fd: ::c_int,
                  iov: *const ::iovec,
                  iovcnt: ::c_int) -> ::ssize_t;
    pub fn readv(fd: ::c_int,
                 iov: *const ::iovec,
                 iovcnt: ::c_int) -> ::ssize_t;

    pub fn sendmsg(fd: ::c_int,
                   msg: *const ::msghdr,
                   flags: ::c_int) -> ::ssize_t;
    pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int)
                   -> ::ssize_t;

    pub fn timegm64(tm: *const ::tm) -> ::time64_t;
}

cfg_if! {
    if #[cfg(target_arch = "x86")] {
        mod x86;
        pub use self::x86::*;
    } else if #[cfg(target_arch = "arm")] {
        mod arm;
        pub use self::arm::*;
    } else {
        // Unknown target_arch
    }
}
<commit_msg>Remove duplicate SYS_gettid<commit_after>// The following definitions are correct for arm and i686,
// but may be wrong for mips

pub type c_long = i32;
pub type c_ulong = u32;
pub type mode_t = u16;
pub type off64_t = ::c_longlong;
pub type sigset_t = ::c_ulong;
pub type socklen_t = i32;
pub type time64_t = i64;

s! {
    pub struct sigaction {
        pub sa_sigaction: ::sighandler_t,
        pub sa_mask: ::sigset_t,
        pub sa_flags: ::c_ulong,
        pub sa_restorer: ::dox::Option<extern fn()>,
    }

    pub struct rlimit64 {
        pub rlim_cur: u64,
        pub rlim_max: u64,
    }

    pub struct stat {
        pub st_dev: ::c_ulonglong,
        __pad0: [::c_uchar; 4],
        __st_ino: ::ino_t,
        pub st_mode: ::c_uint,
        pub st_nlink: ::c_uint,
        pub st_uid: ::uid_t,
        pub st_gid: ::gid_t,
        pub st_rdev: ::c_ulonglong,
        __pad3: [::c_uchar; 4],
        pub st_size: ::c_longlong,
        pub st_blksize: ::blksize_t,
        pub st_blocks: ::c_ulonglong,
        pub st_atime: ::c_ulong,
        pub st_atime_nsec: ::c_ulong,
        pub st_mtime: ::c_ulong,
        pub st_mtime_nsec: ::c_ulong,
        pub st_ctime: ::c_ulong,
        pub st_ctime_nsec: ::c_ulong,
        pub st_ino: ::c_ulonglong,
    }

    pub struct stat64 {
        pub st_dev: ::c_ulonglong,
        __pad0: [::c_uchar; 4],
        __st_ino: ::ino_t,
        pub st_mode: ::c_uint,
        pub st_nlink: ::c_uint,
        pub st_uid: ::uid_t,
        pub st_gid: ::gid_t,
        pub st_rdev: ::c_ulonglong,
        __pad3: [::c_uchar; 4],
        pub st_size: ::c_longlong,
        pub st_blksize: ::blksize_t,
        pub st_blocks: ::c_ulonglong,
        pub st_atime: ::c_ulong,
        pub st_atime_nsec: ::c_ulong,
        pub st_mtime: ::c_ulong,
        pub st_mtime_nsec: ::c_ulong,
        pub st_ctime: ::c_ulong,
        pub st_ctime_nsec: ::c_ulong,
        pub st_ino: ::c_ulonglong,
    }

    pub struct pthread_attr_t {
        pub flags: ::uint32_t,
        pub stack_base: *mut ::c_void,
        pub stack_size: ::size_t,
        pub guard_size: ::size_t,
        pub sched_policy: ::int32_t,
        pub sched_priority: ::int32_t,
    }

    pub struct pthread_mutex_t { value: ::c_int }

    pub struct pthread_cond_t { value: ::c_int }

    pub struct pthread_rwlock_t {
        lock: pthread_mutex_t,
        cond: pthread_cond_t,
        numLocks: ::c_int,
        writerThreadId: ::c_int,
        pendingReaders: ::c_int,
        pendingWriters: ::c_int,
        attr: i32,
        __reserved: [::c_char; 12],
    }

    pub struct passwd {
        pub pw_name: *mut ::c_char,
        pub pw_passwd: *mut ::c_char,
        pub pw_uid: ::uid_t,
        pub pw_gid: ::gid_t,
        pub pw_dir: *mut ::c_char,
        pub pw_shell: *mut ::c_char,
    }

    pub struct statfs {
        pub f_type: ::uint32_t,
        pub f_bsize: ::uint32_t,
        pub f_blocks: ::uint64_t,
        pub f_bfree: ::uint64_t,
        pub f_bavail: ::uint64_t,
        pub f_files: ::uint64_t,
        pub f_ffree: ::uint64_t,
        pub f_fsid: ::__fsid_t,
        pub f_namelen: ::uint32_t,
        pub f_frsize: ::uint32_t,
        pub f_flags: ::uint32_t,
        pub f_spare: [::uint32_t; 4],
    }

    pub struct sysinfo {
        pub uptime: ::c_long,
        pub loads: [::c_ulong; 3],
        pub totalram: ::c_ulong,
        pub freeram: ::c_ulong,
        pub sharedram: ::c_ulong,
        pub bufferram: ::c_ulong,
        pub totalswap: ::c_ulong,
        pub freeswap: ::c_ulong,
        pub procs: ::c_ushort,
        pub pad: ::c_ushort,
        pub totalhigh: ::c_ulong,
        pub freehigh: ::c_ulong,
        pub mem_unit: ::c_uint,
        pub _f: [::c_char; 8],
    }
}

pub const RTLD_GLOBAL: ::c_int = 2;
pub const RTLD_NOW: ::c_int = 0;
pub const RTLD_DEFAULT: *mut ::c_void = -1isize as *mut ::c_void;

pub const PTRACE_GETFPREGS: ::c_int = 14;
pub const PTRACE_SETFPREGS: ::c_int = 15;
pub const PTRACE_GETREGS: ::c_int = 12;
pub const PTRACE_SETREGS: ::c_int = 13;

pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
    value: 0,
};
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
    value: 0,
};
pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
    lock: PTHREAD_MUTEX_INITIALIZER,
    cond: PTHREAD_COND_INITIALIZER,
    numLocks: 0,
    writerThreadId: 0,
    pendingReaders: 0,
    pendingWriters: 0,
    attr: 0,
    __reserved: [0; 12],
};
pub const PTHREAD_STACK_MIN: ::size_t = 4096 * 2;
pub const CPU_SETSIZE: ::size_t = 32;
pub const __CPU_BITS: ::size_t = 32;

pub const UT_LINESIZE: usize = 8;
pub const UT_NAMESIZE: usize = 8;
pub const UT_HOSTSIZE: usize = 16;

pub const SIGSTKSZ: ::size_t = 8192;
pub const MINSIGSTKSZ: ::size_t = 2048;

extern {
    pub fn bind(socket: ::c_int, address: *const ::sockaddr,
                address_len: socklen_t) -> ::c_int;

    pub fn writev(fd: ::c_int,
                  iov: *const ::iovec,
                  iovcnt: ::c_int) -> ::ssize_t;
    pub fn readv(fd: ::c_int,
                 iov: *const ::iovec,
                 iovcnt: ::c_int) -> ::ssize_t;

    pub fn sendmsg(fd: ::c_int,
                   msg: *const ::msghdr,
                   flags: ::c_int) -> ::ssize_t;
    pub fn recvmsg(fd: ::c_int, msg: *mut ::msghdr, flags: ::c_int)
                   -> ::ssize_t;

    pub fn timegm64(tm: *const ::tm) -> ::time64_t;
}

cfg_if! {
    if #[cfg(target_arch = "x86")] {
        mod x86;
        pub use self::x86::*;
    } else if #[cfg(target_arch = "arm")] {
        mod arm;
        pub use self::arm::*;
    } else {
        // Unknown target_arch
    }
}
<|endoftext|>


<commit_before>// while a WIP
#![allow(unused_variables)]
use rutorch::*;
use std::ops::{Index, IndexMut};
use std::convert::From;
use std::cmp::max;
use std::hash::{Hash, Hasher};
use serde::{Serialize, Deserialize, Serializer, Deserializer};

use storage::*;
use ::*;
pub use tensor::tensor_ops::*;
use rand;
use {Ixs, RcMut};

pub enum TensorType {
    Float,
    Double,
    Byte,
    Char,
    Short,
    Int,
    Long,
}

#[derive(Hash, Serialize, Deserialize)]
pub enum TensorKind {
    FloatTensor(Tensor<f32>),
    LongTensor(Tensor<i64>),
}
pub enum NumKind {
    Float(f32),
    Double(f64),
    Long(i64),
}

impl NumKind {
    pub fn intof32(&self) -> f32 {
        use self::NumKind::{Float, Double, Long};
        match *self {
            Float(v) => v,
            Double(v) => unimplemented!(),
            Long(v) => unimplemented!(),
        }
    }
    pub fn intoi64(&self) -> i64 {
        use self::NumKind::{Float, Double, Long};
        match *self {
            Float(v) => unimplemented!(),
            Double(v) => unimplemented!(),
            Long(v) => v,
        }
    }
}

impl<T: Copy> From<T> for NumKind {
    #[allow(unused_variables)]
    default fn from(input: T) -> Self {
        unreachable!()
    }
}
impl From<f32> for NumKind {
    fn from(input: f32) -> Self {
        NumKind::Float(input)
    }
}
impl From<f64> for NumKind {
    fn from(input: f64) -> Self {
        NumKind::Double(input)
    }
}
impl From<i64> for NumKind {
    fn from(input: i64) -> Self {
        NumKind::Long(input)
    }
}

pub type TensorList<T> = Vec<Tensor<T>>;
pub type TensorKindList = Vec<TensorKind>;
pub type OptTensorKindList = Vec<Option<TensorKind>>;
pub type RefTensorList<'a, T> = Vec<&'a mut Tensor<T>>;
pub type RefTensorKindList<'a> = Vec<&'a TensorKind>;
pub type TensorId = usize;

impl TensorKind {
    pub fn backend(&self) -> Box<nn::BackendIntf> {
        unimplemented!()
    }
    pub fn inner(&self) -> *mut ::std::os::raw::c_void {
        unimplemented!()
    }
}

impl Index<usize> for TensorKind {
    type Output = NumKind;
    fn index(&self, idx: usize) -> &Self::Output {
        unimplemented!()
    }
}
impl PartialEq for TensorKind {
    fn eq(&self, other: &Self) -> bool {
        use self::TensorKind::{FloatTensor, LongTensor};
        match (self, other) {
            (&FloatTensor(ref t1), &FloatTensor(ref t2)) => t1.id() == t2.id(),
            (&LongTensor(ref t1), &LongTensor(ref t2)) => t1.id() == t2.id(),
            _ => false,
        }
    }
}
impl Eq for TensorKind {}
impl Clone for TensorKind {
    fn clone(&self) -> Self {
        use self::TensorKind::{FloatTensor, LongTensor};
        match *self {
            FloatTensor(ref t) => FloatTensor(t.clone()),
            LongTensor(ref t) => LongTensor(t.clone()),
        }
    }
}

impl<T> From<Tensor<T>> for TensorKind {
    #[allow(unused_variables)]
    default fn from(input: Tensor<T>) -> Self {
        unreachable!()
    }
}

impl From<Tensor<f32>> for TensorKind {
    fn from(input: Tensor<f32>) -> Self {
        TensorKind::FloatTensor(input)
    }
}

impl From<Tensor<i64>> for TensorKind {
    fn from(input: Tensor<i64>) -> Self {
        TensorKind::LongTensor(input)
    }
}

impl<T> From<TensorKind> for Tensor<T> {
    #[allow(unused_variables)]
    default fn from(input: TensorKind) -> Self {
        panic!("bad cast")
    }
}

impl<'a, T> From<&'a TensorKind> for &'a Tensor<T> {
    #[allow(unused_variables)]
    default fn from(input: &'a TensorKind) -> Self {
        panic!("bad cast")
    }
}

impl<'a> From<&'a TensorKind> for &'a Tensor<f32> {
    fn from(input: &'a TensorKind) -> Self {
        match *input {
            TensorKind::FloatTensor(ref t) => t,
            _ => unreachable!(),
        }
    }
}

impl<'a> From<&'a TensorKind> for &'a Tensor<i64> {
    fn from(input: &'a TensorKind) -> Self {
        match *input {
            TensorKind::LongTensor(ref t) => t,
            _ => unreachable!(),
        }
    }
}

impl From<TensorKind> for Tensor<f32> {
    fn from(input: TensorKind) -> Self {
        match input {
            TensorKind::FloatTensor(v) => v,
            _ => unimplemented!(),
        }
    }
}

impl From<TensorKind> for Tensor<i64> {
    fn from(input: TensorKind) -> Self {
        match input {
            TensorKind::LongTensor(v) => v,
            _ => unimplemented!(),
        }
    }
}

pub struct Tensor<T> {
    pub value: RcMut<TensorImpl<T, Output = T>>,
}

impl<T> Serialize for Tensor<T> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer {
            unimplemented!()
        }
}
impl<'de, T> Deserialize<'de> for Tensor<T> {
     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de> {
            unimplemented!()
        }
}

impl<T: Copy> Hash for Tensor<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.id().hash(state)
    }
}

impl<T: Copy> Index<usize> for Tensor<T> {
    type Output = T;
    fn index(&self, idx: usize) -> &Self::Output {

        //        self.value.borrow_mut().index(idx as isize)
        unimplemented!()
    }
}

impl<T: Copy> Index<i32> for Tensor<T> {
    type Output = T;
    fn index(&self, idx: i32) -> &Self::Output {

        //        self.value.borrow_mut().index(idx as isize)
        unimplemented!()
    }
}

pub trait New<D, T> {
    fn new(args: D) -> T;
}
pub trait NewSelf<D, T> {
    fn new(&self, args: D) -> T;
}

impl<T> NewSelf<usize, Tensor<T>> for Tensor<T> {
    fn new(&self, args: usize) -> Self {
        unimplemented!()
    }
}
impl<T> NewSelf<(), Tensor<T>> for Tensor<T> {
    fn new(&self, args: ()) -> Self {
        unimplemented!()
    }
}
impl<T> NewSelf<Vec<usize>, Tensor<T>> for Tensor<T> {
    fn new(&self, args: Vec<usize>) -> Self {
        unimplemented!()
    }
}
impl NewSelf<usize, TensorKind> for TensorKind {
    fn new(&self, args: usize) -> Self {
        unimplemented!()
    }
}
impl NewSelf<(), TensorKind> for TensorKind {
    fn new(&self, args: ()) -> Self {
        unimplemented!()
    }
}
impl NewSelf<Vec<usize>, TensorKind> for TensorKind {
    fn new(&self, args: Vec<usize>) -> Self {
        unimplemented!()
    }
}
impl NewSelf<[usize; 2], TensorKind> for TensorKind {
    fn new(&self, args: [usize; 2]) -> Self {
        unimplemented!()
    }
}

impl<T> Tensor<T> {
    pub fn len(&self) -> usize {
        unimplemented!()
    }
    pub fn s(&self, dim: usize) -> Self {
        unimplemented!()
    }
}

impl<T> Default for Tensor<T> {
    fn default() -> Self {
        unimplemented!()
    }
}

impl<T> Clone for Tensor<T> {
    fn clone(&self) -> Self {
        Tensor { value: self.value.clone() }
    }
}

impl<T: Copy> Index<isize> for Tensor<T> {
    type Output = T;

    fn index(&self, idx: isize) -> &Self::Output {
        unimplemented!()
    }
}

type RefTI<T> = RcMut<TensorImpl<T, Output = T>>;
pub type TIArg<T> = TensorImpl<T, Output = T>;
pub trait TensorImpl<T>: Index<Ixs, Output = T> {
    //fn view<'a>(&self, dims: &[i32]) -> Tensor<'a>;
    fn new(&self) -> RefTI<T>;
    fn add(&self, value: T, output: &TIArg<T>);
    fn addt(&self, value: T, rhs: &TIArg<T>, output: &TIArg<T>);
    fn inner(&self) -> *mut ::std::os::raw::c_void;
}

impl TensorImpl<f32> for FloatTensor {
    fn new(&self) -> RefTI<f32> {
        // XXX place holder implementation
        RcMutNew(FloatTensor::new())
    }
    fn add(&self, value: f32, output: &TIArg<f32>) {
        let out = typecast!(output.inner(), THFloatTensor);
        unsafe {
            THFloatTensor_add(out, self.t, value);
        };
    }
    fn inner(&self) -> *mut ::std::os::raw::c_void {
        self.t as *mut ::std::os::raw::c_void
    }
    fn addt(&self, value: f32, rhs: &TIArg<f32>, output: &TIArg<f32>) {
        let rhsp = typecast!(rhs.inner(), THFloatTensor);
    }
}

impl Index<isize> for FloatTensor {
    type Output = f32;
    fn index(&self, idx: isize) -> &Self::Output {
        unimplemented!()
    }
}

impl Serialize for FloatTensor {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer {
            unimplemented!()
        }
}
impl<'de> Deserialize<'de> for FloatTensor {
     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de> {
            unimplemented!()
        }
}

pub struct FloatTensor {
    t: *mut THFloatTensor,
    storage: FloatStorage,
    dims: Vec<isize>,
}

impl Default for FloatTensor {
    fn default() -> Self {
        FloatTensor::new()
    }
}

impl FloatTensor {
    pub fn new() -> Self {
        unsafe {
            FloatTensor {
                t: THFloatTensor_new(),
                storage: FloatStorage::new(),
                dims: Vec::new(),
            }
        }
    }
    pub fn with_capacity(dims: &[isize]) -> Self {
        let size = dims.iter().product();
        let storage = FloatStorage::with_capacity(size);
        let strides = vec![1; dims.len()];
        let mut t = THFloatTensor {
            size: dims.clone().as_ptr() as *mut ::std::os::raw::c_long,
            stride: strides.as_ptr() as *mut ::std::os::raw::c_long,
            nDimension: dims.len() as i32,
            storage: storage.t,
            storageOffset: 0,
            refcount: 1,
            flag: TH_TENSOR_REFCOUNTED as i8,
        };
        FloatTensor {
            t: &mut t,
            storage: storage,
            dims: Vec::from(dims),
        }
    }
    pub fn randn(dims: &[isize]) -> Self {
        /* XXX */
        let mut t = FloatTensor::with_capacity(dims);
        for x in t.storage.iter_mut() {
            *x = rand::random::<f32>()
        }
        t
    }
}

impl<'a> Index<&'a [isize]> for FloatTensor {
    type Output = f32;

    fn index(&self, idx: &'a [isize]) -> &Self::Output {
        let mut index: isize = 0;
        let lastidx = max(0, idx.len() as isize - 1) as usize;
        if idx.len() != self.dims.len() {
            panic!("bad dimlen")
        }
        for i in 0..lastidx {
            if idx[i] >= self.dims[i] {
                panic!("bad dimlen")
            }
            index += idx[i] * self.dims[i]
        }
        if idx[lastidx] >= self.dims[lastidx] {
            panic!("bad dimlen")
        }
        index += idx[lastidx];
        &self.storage[index]
    }
}

impl<'a> IndexMut<&'a [isize]> for FloatTensor {
    fn index_mut(&mut self, idx: &'a [isize]) -> &mut Self::Output {
        let mut index: isize = 0;
        let lastidx = max(0, idx.len() as isize - 1) as usize;
        if idx.len() != self.dims.len() {
            panic!("bad dimlen")
        }
        for i in 0..lastidx {
            if idx[i] >= self.dims[i] {
                panic!("bad dimlen")
            }
            index += idx[i] * self.dims[i]
        }
        if idx[lastidx] >= self.dims[lastidx] {
            panic!("bad dimlen")
        }
        index += idx[lastidx];
        &mut self.storage[index]
    }
}

pub fn make_vec(val: usize, count: usize) -> Vec<usize> {
    let mut vec = Vec::new();
    for _ in 0..count {
        vec.push(val)
    }
    vec
}
<commit_msg>format fix<commit_after>// while a WIP
#![allow(unused_variables)]
use rutorch::*;
use std::ops::{Index, IndexMut};
use std::convert::From;
use std::cmp::max;
use std::hash::{Hash, Hasher};
use serde::{Serialize, Deserialize, Serializer, Deserializer};

use storage::*;
use ::*;
pub use tensor::tensor_ops::*;
use rand;
use {Ixs, RcMut};

pub enum TensorType {
    Float,
    Double,
    Byte,
    Char,
    Short,
    Int,
    Long,
}

#[derive(Hash, Serialize, Deserialize)]
pub enum TensorKind {
    FloatTensor(Tensor<f32>),
    LongTensor(Tensor<i64>),
}
pub enum NumKind {
    Float(f32),
    Double(f64),
    Long(i64),
}

impl NumKind {
    pub fn intof32(&self) -> f32 {
        use self::NumKind::{Float, Double, Long};
        match *self {
            Float(v) => v,
            Double(v) => unimplemented!(),
            Long(v) => unimplemented!(),
        }
    }
    pub fn intoi64(&self) -> i64 {
        use self::NumKind::{Float, Double, Long};
        match *self {
            Float(v) => unimplemented!(),
            Double(v) => unimplemented!(),
            Long(v) => v,
        }
    }
}

impl<T: Copy> From<T> for NumKind {
    #[allow(unused_variables)]
    default fn from(input: T) -> Self {
        unreachable!()
    }
}
impl From<f32> for NumKind {
    fn from(input: f32) -> Self {
        NumKind::Float(input)
    }
}
impl From<f64> for NumKind {
    fn from(input: f64) -> Self {
        NumKind::Double(input)
    }
}
impl From<i64> for NumKind {
    fn from(input: i64) -> Self {
        NumKind::Long(input)
    }
}

pub type TensorList<T> = Vec<Tensor<T>>;
pub type TensorKindList = Vec<TensorKind>;
pub type OptTensorKindList = Vec<Option<TensorKind>>;
pub type RefTensorList<'a, T> = Vec<&'a mut Tensor<T>>;
pub type RefTensorKindList<'a> = Vec<&'a TensorKind>;
pub type TensorId = usize;

impl TensorKind {
    pub fn backend(&self) -> Box<nn::BackendIntf> {
        unimplemented!()
    }
    pub fn inner(&self) -> *mut ::std::os::raw::c_void {
        unimplemented!()
    }
}

impl Index<usize> for TensorKind {
    type Output = NumKind;
    fn index(&self, idx: usize) -> &Self::Output {
        unimplemented!()
    }
}
impl PartialEq for TensorKind {
    fn eq(&self, other: &Self) -> bool {
        use self::TensorKind::{FloatTensor, LongTensor};
        match (self, other) {
            (&FloatTensor(ref t1), &FloatTensor(ref t2)) => t1.id() == t2.id(),
            (&LongTensor(ref t1), &LongTensor(ref t2)) => t1.id() == t2.id(),
            _ => false,
        }
    }
}
impl Eq for TensorKind {}
impl Clone for TensorKind {
    fn clone(&self) -> Self {
        use self::TensorKind::{FloatTensor, LongTensor};
        match *self {
            FloatTensor(ref t) => FloatTensor(t.clone()),
            LongTensor(ref t) => LongTensor(t.clone()),
        }
    }
}

impl<T> From<Tensor<T>> for TensorKind {
    #[allow(unused_variables)]
    default fn from(input: Tensor<T>) -> Self {
        unreachable!()
    }
}

impl From<Tensor<f32>> for TensorKind {
    fn from(input: Tensor<f32>) -> Self {
        TensorKind::FloatTensor(input)
    }
}

impl From<Tensor<i64>> for TensorKind {
    fn from(input: Tensor<i64>) -> Self {
        TensorKind::LongTensor(input)
    }
}

impl<T> From<TensorKind> for Tensor<T> {
    #[allow(unused_variables)]
    default fn from(input: TensorKind) -> Self {
        panic!("bad cast")
    }
}

impl<'a, T> From<&'a TensorKind> for &'a Tensor<T> {
    #[allow(unused_variables)]
    default fn from(input: &'a TensorKind) -> Self {
        panic!("bad cast")
    }
}

impl<'a> From<&'a TensorKind> for &'a Tensor<f32> {
    fn from(input: &'a TensorKind) -> Self {
        match *input {
            TensorKind::FloatTensor(ref t) => t,
            _ => unreachable!(),
        }
    }
}

impl<'a> From<&'a TensorKind> for &'a Tensor<i64> {
    fn from(input: &'a TensorKind) -> Self {
        match *input {
            TensorKind::LongTensor(ref t) => t,
            _ => unreachable!(),
        }
    }
}

impl From<TensorKind> for Tensor<f32> {
    fn from(input: TensorKind) -> Self {
        match input {
            TensorKind::FloatTensor(v) => v,
            _ => unimplemented!(),
        }
    }
}

impl From<TensorKind> for Tensor<i64> {
    fn from(input: TensorKind) -> Self {
        match input {
            TensorKind::LongTensor(v) => v,
            _ => unimplemented!(),
        }
    }
}

pub struct Tensor<T> {
    pub value: RcMut<TensorImpl<T, Output = T>>,
}

impl<T> Serialize for Tensor<T> {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        unimplemented!()
    }
}
impl<'de, T> Deserialize<'de> for Tensor<T> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
    {
        unimplemented!()
    }
}

impl<T: Copy> Hash for Tensor<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.id().hash(state)
    }
}

impl<T: Copy> Index<usize> for Tensor<T> {
    type Output = T;
    fn index(&self, idx: usize) -> &Self::Output {

        //        self.value.borrow_mut().index(idx as isize)
        unimplemented!()
    }
}

impl<T: Copy> Index<i32> for Tensor<T> {
    type Output = T;
    fn index(&self, idx: i32) -> &Self::Output {

        //        self.value.borrow_mut().index(idx as isize)
        unimplemented!()
    }
}

pub trait New<D, T> {
    fn new(args: D) -> T;
}
pub trait NewSelf<D, T> {
    fn new(&self, args: D) -> T;
}

impl<T> NewSelf<usize, Tensor<T>> for Tensor<T> {
    fn new(&self, args: usize) -> Self {
        unimplemented!()
    }
}
impl<T> NewSelf<(), Tensor<T>> for Tensor<T> {
    fn new(&self, args: ()) -> Self {
        unimplemented!()
    }
}
impl<T> NewSelf<Vec<usize>, Tensor<T>> for Tensor<T> {
    fn new(&self, args: Vec<usize>) -> Self {
        unimplemented!()
    }
}
impl NewSelf<usize, TensorKind> for TensorKind {
    fn new(&self, args: usize) -> Self {
        unimplemented!()
    }
}
impl NewSelf<(), TensorKind> for TensorKind {
    fn new(&self, args: ()) -> Self {
        unimplemented!()
    }
}
impl NewSelf<Vec<usize>, TensorKind> for TensorKind {
    fn new(&self, args: Vec<usize>) -> Self {
        unimplemented!()
    }
}
impl NewSelf<[usize; 2], TensorKind> for TensorKind {
    fn new(&self, args: [usize; 2]) -> Self {
        unimplemented!()
    }
}

impl<T> Tensor<T> {
    pub fn len(&self) -> usize {
        unimplemented!()
    }
    pub fn s(&self, dim: usize) -> Self {
        unimplemented!()
    }
}

impl<T> Default for Tensor<T> {
    fn default() -> Self {
        unimplemented!()
    }
}

impl<T> Clone for Tensor<T> {
    fn clone(&self) -> Self {
        Tensor { value: self.value.clone() }
    }
}

impl<T: Copy> Index<isize> for Tensor<T> {
    type Output = T;

    fn index(&self, idx: isize) -> &Self::Output {
        unimplemented!()
    }
}

type RefTI<T> = RcMut<TensorImpl<T, Output = T>>;
pub type TIArg<T> = TensorImpl<T, Output = T>;
pub trait TensorImpl<T>: Index<Ixs, Output = T> {
    //fn view<'a>(&self, dims: &[i32]) -> Tensor<'a>;
    fn new(&self) -> RefTI<T>;
    fn add(&self, value: T, output: &TIArg<T>);
    fn addt(&self, value: T, rhs: &TIArg<T>, output: &TIArg<T>);
    fn inner(&self) -> *mut ::std::os::raw::c_void;
}

impl TensorImpl<f32> for FloatTensor {
    fn new(&self) -> RefTI<f32> {
        // XXX place holder implementation
        RcMutNew(FloatTensor::new())
    }
    fn add(&self, value: f32, output: &TIArg<f32>) {
        let out = typecast!(output.inner(), THFloatTensor);
        unsafe {
            THFloatTensor_add(out, self.t, value);
        };
    }
    fn inner(&self) -> *mut ::std::os::raw::c_void {
        self.t as *mut ::std::os::raw::c_void
    }
    fn addt(&self, value: f32, rhs: &TIArg<f32>, output: &TIArg<f32>) {
        let rhsp = typecast!(rhs.inner(), THFloatTensor);
    }
}

impl Index<isize> for FloatTensor {
    type Output = f32;
    fn index(&self, idx: isize) -> &Self::Output {
        unimplemented!()
    }
}

impl Serialize for FloatTensor {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        unimplemented!()
    }
}
impl<'de> Deserialize<'de> for FloatTensor {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
    {
        unimplemented!()
    }
}

pub struct FloatTensor {
    t: *mut THFloatTensor,
    storage: FloatStorage,
    dims: Vec<isize>,
}

impl Default for FloatTensor {
    fn default() -> Self {
        FloatTensor::new()
    }
}

impl FloatTensor {
    pub fn new() -> Self {
        unsafe {
            FloatTensor {
                t: THFloatTensor_new(),
                storage: FloatStorage::new(),
                dims: Vec::new(),
            }
        }
    }
    pub fn with_capacity(dims: &[isize]) -> Self {
        let size = dims.iter().product();
        let storage = FloatStorage::with_capacity(size);
        let strides = vec![1; dims.len()];
        let mut t = THFloatTensor {
            size: dims.clone().as_ptr() as *mut ::std::os::raw::c_long,
            stride: strides.as_ptr() as *mut ::std::os::raw::c_long,
            nDimension: dims.len() as i32,
            storage: storage.t,
            storageOffset: 0,
            refcount: 1,
            flag: TH_TENSOR_REFCOUNTED as i8,
        };
        FloatTensor {
            t: &mut t,
            storage: storage,
            dims: Vec::from(dims),
        }
    }
    pub fn randn(dims: &[isize]) -> Self {
        /* XXX */
        let mut t = FloatTensor::with_capacity(dims);
        for x in t.storage.iter_mut() {
            *x = rand::random::<f32>()
        }
        t
    }
}

impl<'a> Index<&'a [isize]> for FloatTensor {
    type Output = f32;

    fn index(&self, idx: &'a [isize]) -> &Self::Output {
        let mut index: isize = 0;
        let lastidx = max(0, idx.len() as isize - 1) as usize;
        if idx.len() != self.dims.len() {
            panic!("bad dimlen")
        }
        for i in 0..lastidx {
            if idx[i] >= self.dims[i] {
                panic!("bad dimlen")
            }
            index += idx[i] * self.dims[i]
        }
        if idx[lastidx] >= self.dims[lastidx] {
            panic!("bad dimlen")
        }
        index += idx[lastidx];
        &self.storage[index]
    }
}

impl<'a> IndexMut<&'a [isize]> for FloatTensor {
    fn index_mut(&mut self, idx: &'a [isize]) -> &mut Self::Output {
        let mut index: isize = 0;
        let lastidx = max(0, idx.len() as isize - 1) as usize;
        if idx.len() != self.dims.len() {
            panic!("bad dimlen")
        }
        for i in 0..lastidx {
            if idx[i] >= self.dims[i] {
                panic!("bad dimlen")
            }
            index += idx[i] * self.dims[i]
        }
        if idx[lastidx] >= self.dims[lastidx] {
            panic!("bad dimlen")
        }
        index += idx[lastidx];
        &mut self.storage[index]
    }
}

pub fn make_vec(val: usize, count: usize) -> Vec<usize> {
    let mut vec = Vec::new();
    for _ in 0..count {
        vec.push(val)
    }
    vec
}
<|endoftext|>


<commit_before>use js_int::Int;
use serde::{Deserialize, Serialize};
use serde_json::{from_str as from_json_str, value::RawValue as RawJsonValue};

use super::{relation::Relations, room::redaction::SyncRoomRedactionEvent, StateEventContent};
use crate::{
    serde::{CanBeEmpty, Raw},
    OwnedTransactionId,
};

/// Extra information about a message event that is not incorporated into the event's hash.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct MessageLikeUnsigned {
    /// The time in milliseconds that has elapsed since the event was sent.
    ///
    /// This field is generated by the local homeserver, and may be incorrect if the local time on
    /// at least one of the two servers is out of sync, which can cause the age to either be
    /// negative or greater than it actually is.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub age: Option<Int>,

    /// The client-supplied transaction ID, if the client being given the event is the same one
    /// which sent it.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub transaction_id: Option<OwnedTransactionId>,

    /// [Bundled aggregations] of related child events.
    ///
    /// [Bundled aggregations]: https://spec.matrix.org/v1.3/client-server-api/#aggregations
    #[serde(rename = "m.relations", skip_serializing_if = "Option::is_none")]
    pub relations: Option<Relations>,
}

impl MessageLikeUnsigned {
    /// Create a new `Unsigned` with fields set to `None`.
    pub fn new() -> Self {
        Self::default()
    }
}

impl CanBeEmpty for MessageLikeUnsigned {
    /// Whether this unsigned data is empty (all fields are `None`).
    ///
    /// This method is used to determine whether to skip serializing the `unsigned` field in room
    /// events. Do not use it to determine whether an incoming `unsigned` field was present - it
    /// could still have been present but contained none of the known fields.
    fn is_empty(&self) -> bool {
        self.age.is_none() && self.transaction_id.is_none() && self.relations.is_none()
    }
}

/// Extra information about a state event that is not incorporated into the event's hash.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct StateUnsigned<C: StateEventContent> {
    /// The time in milliseconds that has elapsed since the event was sent.
    ///
    /// This field is generated by the local homeserver, and may be incorrect if the local time on
    /// at least one of the two servers is out of sync, which can cause the age to either be
    /// negative or greater than it actually is.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub age: Option<Int>,

    /// The client-supplied transaction ID, if the client being given the event is the same one
    /// which sent it.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub transaction_id: Option<OwnedTransactionId>,

    /// Optional previous content of the event.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub prev_content: Option<C>,

    /// [Bundled aggregations] of related child events.
    ///
    /// [Bundled aggregations]: https://spec.matrix.org/v1.3/client-server-api/#aggregations
    #[serde(rename = "m.relations", skip_serializing_if = "Option::is_none")]
    pub relations: Option<Relations>,
}

impl<C: StateEventContent> StateUnsigned<C> {
    /// Create a new `Unsigned` with fields set to `None`.
    pub fn new() -> Self {
        Self { age: None, transaction_id: None, prev_content: None, relations: None }
    }
}

impl<C: StateEventContent> CanBeEmpty for StateUnsigned<C> {
    /// Whether this unsigned data is empty (all fields are `None`).
    ///
    /// This method is used to determine whether to skip serializing the `unsigned` field in room
    /// events. Do not use it to determine whether an incoming `unsigned` field was present - it
    /// could still have been present but contained none of the known fields.
    fn is_empty(&self) -> bool {
        self.age.is_none()
            && self.transaction_id.is_none()
            && self.prev_content.is_none()
            && self.relations.is_none()
    }
}

/// Helper functions for proc-macro code.
///
/// Needs to be public for UI tests.
#[doc(hidden)]
impl<C: StateEventContent> StateUnsigned<C> {
    pub fn _from_parts(event_type: &str, object: &RawJsonValue) -> serde_json::Result<Self> {
        #[derive(Deserialize)]
        #[serde(bound = "")] // Disable default C: Deserialize bound
        struct WithRawPrevContent<C> {
            #[serde(skip_serializing_if = "Option::is_none")]
            age: Option<Int>,
            #[serde(skip_serializing_if = "Option::is_none")]
            transaction_id: Option<OwnedTransactionId>,
            prev_content: Option<Raw<C>>,
            #[serde(rename = "m.relations", skip_serializing_if = "Option::is_none")]
            relations: Option<Relations>,
        }

        let raw: WithRawPrevContent<C> = from_json_str(object.get())?;
        let prev_content =
            raw.prev_content.map(|r| r.deserialize_content(event_type.into())).transpose()?;

        Ok(Self {
            age: raw.age,
            transaction_id: raw.transaction_id,
            relations: raw.relations,
            prev_content,
        })
    }

    pub fn _map_prev_content<T>(&self, f: impl FnOnce(&C) -> T) -> StateUnsigned<T>
    where
        T: StateEventContent,
    {
        StateUnsigned {
            age: self.age,
            transaction_id: self.transaction_id.clone(),
            prev_content: self.prev_content.as_ref().map(f),
            relations: self.relations.clone(),
        }
    }
}

impl<C: StateEventContent> Default for StateUnsigned<C> {
    fn default() -> Self {
        Self::new()
    }
}

/// Extra information about a redacted event that is not incorporated into the event's hash.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct RedactedUnsigned {
    /// The event that redacted this event, if any.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub redacted_because: Option<Box<SyncRoomRedactionEvent>>,
}

impl RedactedUnsigned {
    /// Create a new `RedactedUnsigned` with field set to `None`.
    pub fn new() -> Self {
        Self::default()
    }

    /// Create a new `RedactedUnsigned` with the given redacted because.
    pub fn new_because(redacted_because: Box<SyncRoomRedactionEvent>) -> Self {
        Self { redacted_because: Some(redacted_because) }
    }
}

impl CanBeEmpty for RedactedUnsigned {
    /// Whether this unsigned data is empty (`redacted_because` is `None`).
    ///
    /// This method is used to determine whether to skip serializing the `unsigned` field in
    /// redacted room events. Do not use it to determine whether an incoming `unsigned` field
    /// was present - it could still have been present but contained none of the known fields.
    fn is_empty(&self) -> bool {
        self.redacted_because.is_none()
    }
}
<commit_msg>events: Remove unused function<commit_after>use js_int::Int;
use serde::{Deserialize, Serialize};
use serde_json::{from_str as from_json_str, value::RawValue as RawJsonValue};

use super::{relation::Relations, room::redaction::SyncRoomRedactionEvent, StateEventContent};
use crate::{
    serde::{CanBeEmpty, Raw},
    OwnedTransactionId,
};

/// Extra information about a message event that is not incorporated into the event's hash.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct MessageLikeUnsigned {
    /// The time in milliseconds that has elapsed since the event was sent.
    ///
    /// This field is generated by the local homeserver, and may be incorrect if the local time on
    /// at least one of the two servers is out of sync, which can cause the age to either be
    /// negative or greater than it actually is.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub age: Option<Int>,

    /// The client-supplied transaction ID, if the client being given the event is the same one
    /// which sent it.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub transaction_id: Option<OwnedTransactionId>,

    /// [Bundled aggregations] of related child events.
    ///
    /// [Bundled aggregations]: https://spec.matrix.org/v1.3/client-server-api/#aggregations
    #[serde(rename = "m.relations", skip_serializing_if = "Option::is_none")]
    pub relations: Option<Relations>,
}

impl MessageLikeUnsigned {
    /// Create a new `Unsigned` with fields set to `None`.
    pub fn new() -> Self {
        Self::default()
    }
}

impl CanBeEmpty for MessageLikeUnsigned {
    /// Whether this unsigned data is empty (all fields are `None`).
    ///
    /// This method is used to determine whether to skip serializing the `unsigned` field in room
    /// events. Do not use it to determine whether an incoming `unsigned` field was present - it
    /// could still have been present but contained none of the known fields.
    fn is_empty(&self) -> bool {
        self.age.is_none() && self.transaction_id.is_none() && self.relations.is_none()
    }
}

/// Extra information about a state event that is not incorporated into the event's hash.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct StateUnsigned<C: StateEventContent> {
    /// The time in milliseconds that has elapsed since the event was sent.
    ///
    /// This field is generated by the local homeserver, and may be incorrect if the local time on
    /// at least one of the two servers is out of sync, which can cause the age to either be
    /// negative or greater than it actually is.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub age: Option<Int>,

    /// The client-supplied transaction ID, if the client being given the event is the same one
    /// which sent it.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub transaction_id: Option<OwnedTransactionId>,

    /// Optional previous content of the event.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub prev_content: Option<C>,

    /// [Bundled aggregations] of related child events.
    ///
    /// [Bundled aggregations]: https://spec.matrix.org/v1.3/client-server-api/#aggregations
    #[serde(rename = "m.relations", skip_serializing_if = "Option::is_none")]
    pub relations: Option<Relations>,
}

impl<C: StateEventContent> StateUnsigned<C> {
    /// Create a new `Unsigned` with fields set to `None`.
    pub fn new() -> Self {
        Self { age: None, transaction_id: None, prev_content: None, relations: None }
    }
}

impl<C: StateEventContent> CanBeEmpty for StateUnsigned<C> {
    /// Whether this unsigned data is empty (all fields are `None`).
    ///
    /// This method is used to determine whether to skip serializing the `unsigned` field in room
    /// events. Do not use it to determine whether an incoming `unsigned` field was present - it
    /// could still have been present but contained none of the known fields.
    fn is_empty(&self) -> bool {
        self.age.is_none()
            && self.transaction_id.is_none()
            && self.prev_content.is_none()
            && self.relations.is_none()
    }
}

/// Helper functions for proc-macro code.
///
/// Needs to be public for UI tests.
#[doc(hidden)]
impl<C: StateEventContent> StateUnsigned<C> {
    pub fn _from_parts(event_type: &str, object: &RawJsonValue) -> serde_json::Result<Self> {
        #[derive(Deserialize)]
        #[serde(bound = "")] // Disable default C: Deserialize bound
        struct WithRawPrevContent<C> {
            #[serde(skip_serializing_if = "Option::is_none")]
            age: Option<Int>,
            #[serde(skip_serializing_if = "Option::is_none")]
            transaction_id: Option<OwnedTransactionId>,
            prev_content: Option<Raw<C>>,
            #[serde(rename = "m.relations", skip_serializing_if = "Option::is_none")]
            relations: Option<Relations>,
        }

        let raw: WithRawPrevContent<C> = from_json_str(object.get())?;
        let prev_content =
            raw.prev_content.map(|r| r.deserialize_content(event_type.into())).transpose()?;

        Ok(Self {
            age: raw.age,
            transaction_id: raw.transaction_id,
            relations: raw.relations,
            prev_content,
        })
    }
}

impl<C: StateEventContent> Default for StateUnsigned<C> {
    fn default() -> Self {
        Self::new()
    }
}

/// Extra information about a redacted event that is not incorporated into the event's hash.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct RedactedUnsigned {
    /// The event that redacted this event, if any.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub redacted_because: Option<Box<SyncRoomRedactionEvent>>,
}

impl RedactedUnsigned {
    /// Create a new `RedactedUnsigned` with field set to `None`.
    pub fn new() -> Self {
        Self::default()
    }

    /// Create a new `RedactedUnsigned` with the given redacted because.
    pub fn new_because(redacted_because: Box<SyncRoomRedactionEvent>) -> Self {
        Self { redacted_because: Some(redacted_because) }
    }
}

impl CanBeEmpty for RedactedUnsigned {
    /// Whether this unsigned data is empty (`redacted_because` is `None`).
    ///
    /// This method is used to determine whether to skip serializing the `unsigned` field in
    /// redacted room events. Do not use it to determine whether an incoming `unsigned` field
    /// was present - it could still have been present but contained none of the known fields.
    fn is_empty(&self) -> bool {
        self.redacted_because.is_none()
    }
}
<|endoftext|>