<commit_before>/*
 * Copyright (c) 2012, Ben Noordhuis <info@bnoordhuis.nl>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#[license = "ISC"];

#[link(name = "epoll",
       vers = "1.0",
       author = "Ben Noordhuis <info@bnoordhuis.nl>")];

use std; // required by the tests

import c_int = ctypes::c_int;

//const EPOLL_NONBLOCK: int = 0x800;
const EPOLL_CLOEXEC: int = 0x80000;

const EPOLL_CTL_ADD: int = 1;
const EPOLL_CTL_DEL: int = 2;
const EPOLL_CTL_MOD: int = 3;

const EPOLLIN: i32 = 0x01i32;
const EPOLLPRI: i32 = 0x02i32;
const EPOLLOUT: i32 = 0x04i32;
const EPOLLERR: i32 = 0x08i32;
const EPOLLHUP: i32 = 0x10i32;
const EPOLLONESHOT: i32 = 0x40000000i32;
const EPOLLET: i32 = 0x80000000i32;

type epoll_event = {
  events: i32,
  data: u64
};

#[nolink]
native mod __glibc {
  fn epoll_create1(flags: c_int) -> c_int;
  fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: epoll_event) -> c_int;
  fn epoll_wait(epfd: c_int,
                events: *mutable epoll_event,
                maxevents: c_int,
                timeout: c_int) -> c_int;
}

fn epoll_create1(flags: int) -> int {
  __glibc::epoll_create1(flags as c_int) as int
}

fn epoll_ctl(epfd: int, op: int, fd: int, event: epoll_event) -> int {
  __glibc::epoll_ctl(epfd as c_int, op as c_int, fd as c_int, event) as int
}

fn epoll_wait(epfd: int, events: [mutable epoll_event], timeout: int) -> int {
  let pevents: *mutable epoll_event = ptr::mut_addr_of(events[0]);
  let maxevents: c_int = vec::len(events) as c_int;
  ret __glibc::epoll_wait(epfd as c_int,
                          pevents,
                          maxevents,
                          timeout as c_int) as int;
}

#[test]
fn test_epoll_create1() {
  assert epoll_create1(0) >= 0;
  assert epoll_create1(EPOLL_CLOEXEC) >= 0;
  assert epoll_create1(-1) == -1;
}

#[test]
fn test_epoll_ctl() {
  let epfd = epoll_create1(0);
  assert epfd >= 0;

  assert epoll_ctl(epfd, EPOLL_CTL_ADD, 0, {events:EPOLLIN, data:0u64}) == 0;
  assert epoll_ctl(epfd, EPOLL_CTL_ADD, 0, {events:EPOLLIN, data:0u64}) == -1;
  assert epoll_ctl(epfd, EPOLL_CTL_MOD, 0, {events:EPOLLOUT, data:0u64}) == 0;
  assert epoll_ctl(epfd, EPOLL_CTL_DEL, 0, {events:EPOLLIN, data:0u64}) == 0;

  assert epoll_ctl(epfd, EPOLL_CTL_ADD, -1, {events:EPOLLIN, data:0u64}) == -1;
  assert epoll_ctl(epfd, EPOLL_CTL_MOD, -1, {events:EPOLLIN, data:0u64}) == -1;
  assert epoll_ctl(epfd, EPOLL_CTL_DEL, -1, {events:EPOLLIN, data:0u64}) == -1;
}

#[test]
fn test_epoll_wait() {
  // add stdout to epoll set and wait for it to become writable
  // should be immediate, it's an error if we hit the 50 ms timeout
  let epfd = epoll_create1(0);
  assert epfd >= 0;

  let magic = 42u64;
  assert epoll_ctl(epfd, EPOLL_CTL_ADD, 1, {events:EPOLLOUT, data:magic}) == 0;

  let events: [mutable epoll_event] = [mutable {events:0i32, data:0u64}];
  let n = epoll_wait(epfd, events, 50);
  assert n == 1;
  assert events[0].data == magic;
  assert events[0].events & EPOLLOUT == EPOLLOUT;
}
<commit_msg>Add failing test.<commit_after>/*
 * Copyright (c) 2012, Ben Noordhuis <info@bnoordhuis.nl>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#[license = "ISC"];

#[link(name = "epoll",
       vers = "1.0",
       author = "Ben Noordhuis <info@bnoordhuis.nl>")];

use std; // required by the tests

import c_int = ctypes::c_int;

//const EPOLL_NONBLOCK: int = 0x800;
const EPOLL_CLOEXEC: int = 0x80000;

const EPOLL_CTL_ADD: int = 1;
const EPOLL_CTL_DEL: int = 2;
const EPOLL_CTL_MOD: int = 3;

const EPOLLIN: i32 = 0x01i32;
const EPOLLPRI: i32 = 0x02i32;
const EPOLLOUT: i32 = 0x04i32;
const EPOLLERR: i32 = 0x08i32;
const EPOLLHUP: i32 = 0x10i32;
const EPOLLONESHOT: i32 = 0x40000000i32;
const EPOLLET: i32 = 0x80000000i32;

type epoll_event = {
  events: i32,
  data: u64
};

#[nolink]
native mod __glibc {
  fn epoll_create1(flags: c_int) -> c_int;
  fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: epoll_event) -> c_int;
  fn epoll_wait(epfd: c_int,
                events: *mutable epoll_event,
                maxevents: c_int,
                timeout: c_int) -> c_int;
}

fn epoll_create1(flags: int) -> int {
  __glibc::epoll_create1(flags as c_int) as int
}

fn epoll_ctl(epfd: int, op: int, fd: int, event: epoll_event) -> int {
  __glibc::epoll_ctl(epfd as c_int, op as c_int, fd as c_int, event) as int
}

fn epoll_wait(epfd: int, events: [mutable epoll_event], timeout: int) -> int {
  let pevents: *mutable epoll_event = ptr::mut_addr_of(events[0]);
  let maxevents: c_int = vec::len(events) as c_int;
  ret __glibc::epoll_wait(epfd as c_int,
                          pevents,
                          maxevents,
                          timeout as c_int) as int;
}

#[test]
fn test_epoll_create1() {
  assert epoll_create1(0) >= 0;
  assert epoll_create1(EPOLL_CLOEXEC) >= 0;
  assert epoll_create1(-1) == -1;
}

#[test]
fn test_epoll_ctl() {
  let epfd = epoll_create1(0);
  assert epfd >= 0;

  assert epoll_ctl(epfd, EPOLL_CTL_ADD, 0, {events:EPOLLIN, data:0u64}) == 0;
  assert epoll_ctl(epfd, EPOLL_CTL_ADD, 0, {events:EPOLLIN, data:0u64}) == -1;
  assert epoll_ctl(epfd, EPOLL_CTL_MOD, 0, {events:EPOLLOUT, data:0u64}) == 0;
  assert epoll_ctl(epfd, EPOLL_CTL_DEL, 0, {events:EPOLLIN, data:0u64}) == 0;

  assert epoll_ctl(epfd, EPOLL_CTL_ADD, -1, {events:EPOLLIN, data:0u64}) == -1;
  assert epoll_ctl(epfd, EPOLL_CTL_MOD, -1, {events:EPOLLIN, data:0u64}) == -1;
  assert epoll_ctl(epfd, EPOLL_CTL_DEL, -1, {events:EPOLLIN, data:0u64}) == -1;
}

#[test]
fn test_epoll_wait() {
  // add stdout to epoll set and wait for it to become writable
  // should be immediate, it's an error if we hit the 50 ms timeout
  let epfd = epoll_create1(0);
  assert epfd >= 0;

  let magic = 42u64;
  assert epoll_ctl(epfd, EPOLL_CTL_ADD, 1, {events:EPOLLOUT, data:magic}) == 0;
  assert epoll_ctl(epfd, EPOLL_CTL_ADD, 2, {events:EPOLLOUT, data:magic}) == 0;

  let events: [mutable epoll_event] = [
    mutable {events:0i32, data:0u64}, {events:0i32, data:0u64}];

  let n = epoll_wait(epfd, events, 50);
  assert n == 2;
  assert events[0].data == magic;
  assert events[0].events & EPOLLOUT == EPOLLOUT;
}
<|endoftext|>


<commit_before>//! ## List Tables
//!
//! The following code shows a simple example of using Rusoto's DynamoDB API to
//! list the names of all tables in a database.
extern crate rusoto_core;
extern crate rusoto_dynamodb;

use rusoto_core::Region;
use rusoto_dynamodb::{DynamoDb, DynamoDbClient, ListTablesInput};

fn main() {
    let client = DynamoDbClient::simple(Region::UsEast1);
    let list_tables_input: ListTablesInput = Default::default();

    match client.list_tables(list_tables_input).sync() {
        Ok(output) => {
            match output.table_names {
                Some(table_name_list) => {
                    println!("Tables in database:");

                    for table_name in table_name_list {
                        println!("{}", table_name);
                    }
                },
                None => println!("No tables in database!"),
            }
        },
        Err(error) => {
            println!("Error: {:?}", error);
        },
    }
}
<commit_msg>fix dynamodb example<commit_after>//! ## List Tables
//!
//! The following code shows a simple example of using Rusoto's DynamoDB API to
//! list the names of all tables in a database.
extern crate rusoto_core;
extern crate rusoto_dynamodb;

use rusoto_core::Region;
use rusoto_dynamodb::{DynamoDb, DynamoDbClient, ListTablesInput};

fn main() {
    let client = DynamoDbClient::new(Region::UsEast1);
    let list_tables_input: ListTablesInput = Default::default();

    match client.list_tables(list_tables_input).sync() {
        Ok(output) => {
            match output.table_names {
                Some(table_name_list) => {
                    println!("Tables in database:");

                    for table_name in table_name_list {
                        println!("{}", table_name);
                    }
                },
                None => println!("No tables in database!"),
            }
        },
        Err(error) => {
            println!("Error: {:?}", error);
        },
    }
}
<|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::fmt;
use std::hash::Hash;
use std::slice::Iter;

use common::ArgumentName;
use common::DirectiveName;
use common::Named;
use common::NamedItem;
use common::WithLocation;
use graphql_syntax::ConstantValue;
use graphql_syntax::DirectiveLocation;
use intern::string_key::Intern;
use intern::string_key::StringKey;
use lazy_static::lazy_static;

lazy_static! {
    static ref DIRECTIVE_DEPRECATED: DirectiveName = DirectiveName("deprecated".intern());
    static ref ARGUMENT_REASON: ArgumentName = ArgumentName("reason".intern());
}

pub(crate) type TypeMap = HashMap<StringKey, Type>;

macro_rules! type_id {
    ($name:ident, $type:ident) => {
        #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
        pub struct $name(pub $type);
        impl $name {
            pub(crate) fn as_usize(&self) -> usize {
                self.0 as usize
            }
        }

        impl fmt::Debug for $name {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                write!(f, "{}({})", stringify!($name), self.0)
            }
        }

        impl fmt::Display for $name {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                write!(f, "{}", self.0)
            }
        }
    };
}

type_id!(EnumID, u32);
type_id!(InputObjectID, u32);
type_id!(InterfaceID, u32);
type_id!(ObjectID, u32);
type_id!(ScalarID, u32);
type_id!(UnionID, u32);
type_id!(FieldID, u32);

#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Type {
    Enum(EnumID),
    InputObject(InputObjectID),
    Interface(InterfaceID),
    Object(ObjectID),
    Scalar(ScalarID),
    Union(UnionID),
}

impl Type {
    pub fn is_scalar(self) -> bool {
        matches!(self, Type::Scalar(_))
    }

    pub fn is_enum(self) -> bool {
        matches!(self, Type::Enum(_))
    }

    pub fn is_input_type(self) -> bool {
        matches!(self, Type::Scalar(_) | Type::Enum(_) | Type::InputObject(_))
    }

    pub fn is_abstract_type(self) -> bool {
        matches!(self, Type::Union(_) | Type::Interface(_))
    }

    pub fn is_composite_type(self) -> bool {
        matches!(self, Type::Object(_) | Type::Interface(_) | Type::Union(_))
    }

    pub fn is_object(self) -> bool {
        matches!(self, Type::Object(_))
    }

    pub fn is_input_object(self) -> bool {
        matches!(self, Type::InputObject(_))
    }

    pub fn is_interface(self) -> bool {
        matches!(self, Type::Interface(_))
    }

    pub fn is_object_or_interface(self) -> bool {
        matches!(self, Type::Object(_) | Type::Interface(_))
    }

    pub fn is_union(self) -> bool {
        matches!(self, Type::Union(_))
    }

    pub fn get_enum_id(self) -> Option<EnumID> {
        match self {
            Type::Enum(id) => Some(id),
            _ => None,
        }
    }

    pub fn get_input_object_id(self) -> Option<InputObjectID> {
        match self {
            Type::InputObject(id) => Some(id),
            _ => None,
        }
    }

    pub fn get_interface_id(self) -> Option<InterfaceID> {
        match self {
            Type::Interface(id) => Some(id),
            _ => None,
        }
    }

    pub fn get_object_id(self) -> Option<ObjectID> {
        match self {
            Type::Object(id) => Some(id),
            _ => None,
        }
    }

    pub fn get_scalar_id(self) -> Option<ScalarID> {
        match self {
            Type::Scalar(id) => Some(id),
            _ => None,
        }
    }

    pub fn get_union_id(self) -> Option<UnionID> {
        match self {
            Type::Union(id) => Some(id),
            _ => None,
        }
    }
}

impl fmt::Debug for Type {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Type::Enum(id) => f.write_fmt(format_args!("Enum({:?})", id.0)),
            Type::InputObject(id) => f.write_fmt(format_args!("InputObject({:?})", id.0)),
            Type::Interface(id) => f.write_fmt(format_args!("Interface({:?})", id.0)),
            Type::Object(id) => f.write_fmt(format_args!("Object({:?})", id.0)),
            Type::Scalar(id) => f.write_fmt(format_args!("Scalar({:?})", id.0)),
            Type::Union(id) => f.write_fmt(format_args!("Union({:?})", id.0)),
        }
    }
}

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum TypeReference {
    Named(Type),
    NonNull(Box<TypeReference>),
    List(Box<TypeReference>),
}

impl TypeReference {
    pub fn inner(&self) -> Type {
        match self {
            TypeReference::Named(type_) => *type_,
            TypeReference::List(of) => of.inner(),
            TypeReference::NonNull(of) => of.inner(),
        }
    }

    pub fn non_null(&self) -> TypeReference {
        match self {
            TypeReference::Named(_) => TypeReference::NonNull(Box::new(self.clone())),
            TypeReference::List(_) => TypeReference::NonNull(Box::new(self.clone())),
            TypeReference::NonNull(_) => self.clone(),
        }
    }

    pub fn nullable_type(&self) -> &TypeReference {
        match self {
            TypeReference::Named(_) => self,
            TypeReference::List(_) => self,
            TypeReference::NonNull(of) => of,
        }
    }

    pub fn is_non_null(&self) -> bool {
        matches!(self, TypeReference::NonNull(_))
    }

    pub fn is_list(&self) -> bool {
        matches!(self.nullable_type(), TypeReference::List(_))
    }

    // If the type is Named or NonNull<Named> return the inner named.
    // If the type is a List or NonNull<List> returns a matching list with nullable items.
    pub fn with_nullable_item_type(&self) -> TypeReference {
        match self {
            TypeReference::Named(_) => self.clone(),
            TypeReference::List(of) => TypeReference::List(Box::new(of.nullable_type().clone())),
            TypeReference::NonNull(of) => {
                let inner: &TypeReference = of;
                match inner {
                    TypeReference::List(_) => {
                        TypeReference::NonNull(Box::new(of.with_nullable_item_type()))
                    }
                    TypeReference::Named(_) => inner.clone(),
                    TypeReference::NonNull(_) => {
                        unreachable!("Invalid nested TypeReference::NonNull")
                    }
                }
            }
        }
    }

    pub fn list_item_type(&self) -> Option<&TypeReference> {
        match self.nullable_type() {
            TypeReference::List(of) => Some(of),
            _ => None,
        }
    }

    // Return None if the type is a List, otherwise return the inner type
    pub fn non_list_type(&self) -> Option<Type> {
        match self {
            TypeReference::List(_) => None,
            TypeReference::Named(type_) => Some(*type_),
            TypeReference::NonNull(of) => of.non_list_type(),
        }
    }
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Directive {
    pub name: DirectiveName,
    pub arguments: ArgumentDefinitions,
    pub locations: Vec<DirectiveLocation>,
    pub repeatable: bool,
    pub is_extension: bool,
    pub description: Option<StringKey>,
}

impl Named for Directive {
    type Name = DirectiveName;
    fn name(&self) -> DirectiveName {
        self.name
    }
}

#[derive(Clone, Debug)]
pub struct Scalar {
    pub name: WithLocation<StringKey>,
    pub is_extension: bool,
    pub directives: Vec<DirectiveValue>,
    pub description: Option<StringKey>,
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct Object {
    pub name: WithLocation<StringKey>,
    pub is_extension: bool,
    pub fields: Vec<FieldID>,
    pub interfaces: Vec<InterfaceID>,
    pub directives: Vec<DirectiveValue>,
    pub description: Option<StringKey>,
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct InputObject {
    pub name: WithLocation<StringKey>,
    pub fields: ArgumentDefinitions,
    pub directives: Vec<DirectiveValue>,
    pub description: Option<StringKey>,
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct Enum {
    pub name: WithLocation<StringKey>,
    pub is_extension: bool,
    pub values: Vec<EnumValue>,
    pub directives: Vec<DirectiveValue>,
    pub description: Option<StringKey>,
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct Union {
    pub name: WithLocation<StringKey>,
    pub is_extension: bool,
    pub members: Vec<ObjectID>,
    pub directives: Vec<DirectiveValue>,
    pub description: Option<StringKey>,
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct Interface {
    pub name: WithLocation<StringKey>,
    pub is_extension: bool,
    pub implementing_interfaces: Vec<InterfaceID>,
    pub implementing_objects: Vec<ObjectID>,
    pub fields: Vec<FieldID>,
    pub directives: Vec<DirectiveValue>,
    pub interfaces: Vec<InterfaceID>,
    pub description: Option<StringKey>,
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct Field {
    pub name: WithLocation<StringKey>,
    pub is_extension: bool,
    pub arguments: ArgumentDefinitions,
    pub type_: TypeReference,
    pub directives: Vec<DirectiveValue>,
    /// The type on which this field was defined. This field is (should)
    /// always be set, except for special fields such as __typename and
    /// __id, which are queryable on all types and therefore don't have
    /// a single parent type.
    pub parent_type: Option<Type>,
    pub description: Option<StringKey>,
}

pub struct Deprecation {
    pub reason: Option<StringKey>,
}

impl Field {
    pub fn deprecated(&self) -> Option<Deprecation> {
        self.directives
            .named(*DIRECTIVE_DEPRECATED)
            .map(|directive| Deprecation {
                reason: directive
                    .arguments
                    .named(*ARGUMENT_REASON)
                    .and_then(|reason| reason.value.get_string_literal()),
            })
    }
}

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Argument {
    pub name: ArgumentName,
    pub type_: TypeReference,
    pub default_value: Option<ConstantValue>,
    pub description: Option<StringKey>,
    pub directives: Vec<DirectiveValue>,
}

impl Named for Argument {
    type Name = ArgumentName;
    fn name(&self) -> ArgumentName {
        self.name
    }
}

#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct ArgumentValue {
    pub name: ArgumentName,
    pub value: ConstantValue,
}

#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct DirectiveValue {
    pub name: DirectiveName,
    pub arguments: Vec<ArgumentValue>,
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct EnumValue {
    pub value: StringKey,
    pub directives: Vec<DirectiveValue>,
}

#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ArgumentDefinitions(pub(crate) Vec<Argument>);

impl ArgumentDefinitions {
    pub fn new(arguments: Vec<Argument>) -> Self {
        Self(arguments)
    }

    pub fn named(&self, name: ArgumentName) -> Option<&Argument> {
        self.0.named(name)
    }

    pub fn contains(&self, name: StringKey) -> bool {
        self.0.iter().any(|x| x.name == ArgumentName(name))
    }

    pub fn iter(&self) -> Iter<'_, Argument> {
        self.0.iter()
    }

    pub fn is_empty(&self) -> bool {
        self.0.is_empty()
    }
}

impl fmt::Debug for ArgumentDefinitions {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_fmt(format_args!("{:#?}", self.0))
    }
}

impl IntoIterator for ArgumentDefinitions {
    type Item = Argument;
    type IntoIter = std::vec::IntoIter<Self::Item>;

    fn into_iter(self) -> Self::IntoIter {
        self.0.into_iter()
    }
}

pub trait TypeWithFields {
    fn fields(&self) -> &Vec<FieldID>;
    fn interfaces(&self) -> &Vec<InterfaceID>;
}

impl TypeWithFields for Interface {
    fn fields(&self) -> &Vec<FieldID> {
        &self.fields
    }

    fn interfaces(&self) -> &Vec<InterfaceID> {
        &self.interfaces
    }
}

impl TypeWithFields for Object {
    fn fields(&self) -> &Vec<FieldID> {
        &self.fields
    }

    fn interfaces(&self) -> &Vec<InterfaceID> {
        &self.interfaces
    }
}

#[allow(unused_macros)]
macro_rules! impl_named {
    ($type_name:ident) => {
        impl Named for $type_name {
            type Name = StringKey;
            fn name(&self) -> StringKey {
                self.name
            }
        }
    };
}

macro_rules! impl_named_for_with_location {
    ($type_name:ident) => {
        impl Named for $type_name {
            type Name = StringKey;
            fn name(&self) -> StringKey {
                self.name.item
            }
        }
    };
}

impl_named_for_with_location!(Object);
impl_named_for_with_location!(Field);
impl_named_for_with_location!(InputObject);
impl_named_for_with_location!(Interface);
impl_named_for_with_location!(Union);
impl_named_for_with_location!(Scalar);
impl_named_for_with_location!(Enum);

impl Named for DirectiveValue {
    type Name = DirectiveName;
    fn name(&self) -> DirectiveName {
        self.name
    }
}

impl Named for ArgumentValue {
    type Name = ArgumentName;
    fn name(&self) -> ArgumentName {
        self.name
    }
}
<commit_msg>Give `impl_named_for_with_location!` a second parameter `$name_type`<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::fmt;
use std::hash::Hash;
use std::slice::Iter;

use common::ArgumentName;
use common::DirectiveName;
use common::Named;
use common::NamedItem;
use common::WithLocation;
use graphql_syntax::ConstantValue;
use graphql_syntax::DirectiveLocation;
use intern::string_key::Intern;
use intern::string_key::StringKey;
use lazy_static::lazy_static;

lazy_static! {
    static ref DIRECTIVE_DEPRECATED: DirectiveName = DirectiveName("deprecated".intern());
    static ref ARGUMENT_REASON: ArgumentName = ArgumentName("reason".intern());
}

pub(crate) type TypeMap = HashMap<StringKey, Type>;

macro_rules! type_id {
    ($name:ident, $type:ident) => {
        #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
        pub struct $name(pub $type);
        impl $name {
            pub(crate) fn as_usize(&self) -> usize {
                self.0 as usize
            }
        }

        impl fmt::Debug for $name {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                write!(f, "{}({})", stringify!($name), self.0)
            }
        }

        impl fmt::Display for $name {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                write!(f, "{}", self.0)
            }
        }
    };
}

type_id!(EnumID, u32);
type_id!(InputObjectID, u32);
type_id!(InterfaceID, u32);
type_id!(ObjectID, u32);
type_id!(ScalarID, u32);
type_id!(UnionID, u32);
type_id!(FieldID, u32);

#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Type {
    Enum(EnumID),
    InputObject(InputObjectID),
    Interface(InterfaceID),
    Object(ObjectID),
    Scalar(ScalarID),
    Union(UnionID),
}

impl Type {
    pub fn is_scalar(self) -> bool {
        matches!(self, Type::Scalar(_))
    }

    pub fn is_enum(self) -> bool {
        matches!(self, Type::Enum(_))
    }

    pub fn is_input_type(self) -> bool {
        matches!(self, Type::Scalar(_) | Type::Enum(_) | Type::InputObject(_))
    }

    pub fn is_abstract_type(self) -> bool {
        matches!(self, Type::Union(_) | Type::Interface(_))
    }

    pub fn is_composite_type(self) -> bool {
        matches!(self, Type::Object(_) | Type::Interface(_) | Type::Union(_))
    }

    pub fn is_object(self) -> bool {
        matches!(self, Type::Object(_))
    }

    pub fn is_input_object(self) -> bool {
        matches!(self, Type::InputObject(_))
    }

    pub fn is_interface(self) -> bool {
        matches!(self, Type::Interface(_))
    }

    pub fn is_object_or_interface(self) -> bool {
        matches!(self, Type::Object(_) | Type::Interface(_))
    }

    pub fn is_union(self) -> bool {
        matches!(self, Type::Union(_))
    }

    pub fn get_enum_id(self) -> Option<EnumID> {
        match self {
            Type::Enum(id) => Some(id),
            _ => None,
        }
    }

    pub fn get_input_object_id(self) -> Option<InputObjectID> {
        match self {
            Type::InputObject(id) => Some(id),
            _ => None,
        }
    }

    pub fn get_interface_id(self) -> Option<InterfaceID> {
        match self {
            Type::Interface(id) => Some(id),
            _ => None,
        }
    }

    pub fn get_object_id(self) -> Option<ObjectID> {
        match self {
            Type::Object(id) => Some(id),
            _ => None,
        }
    }

    pub fn get_scalar_id(self) -> Option<ScalarID> {
        match self {
            Type::Scalar(id) => Some(id),
            _ => None,
        }
    }

    pub fn get_union_id(self) -> Option<UnionID> {
        match self {
            Type::Union(id) => Some(id),
            _ => None,
        }
    }
}

impl fmt::Debug for Type {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Type::Enum(id) => f.write_fmt(format_args!("Enum({:?})", id.0)),
            Type::InputObject(id) => f.write_fmt(format_args!("InputObject({:?})", id.0)),
            Type::Interface(id) => f.write_fmt(format_args!("Interface({:?})", id.0)),
            Type::Object(id) => f.write_fmt(format_args!("Object({:?})", id.0)),
            Type::Scalar(id) => f.write_fmt(format_args!("Scalar({:?})", id.0)),
            Type::Union(id) => f.write_fmt(format_args!("Union({:?})", id.0)),
        }
    }
}

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum TypeReference {
    Named(Type),
    NonNull(Box<TypeReference>),
    List(Box<TypeReference>),
}

impl TypeReference {
    pub fn inner(&self) -> Type {
        match self {
            TypeReference::Named(type_) => *type_,
            TypeReference::List(of) => of.inner(),
            TypeReference::NonNull(of) => of.inner(),
        }
    }

    pub fn non_null(&self) -> TypeReference {
        match self {
            TypeReference::Named(_) => TypeReference::NonNull(Box::new(self.clone())),
            TypeReference::List(_) => TypeReference::NonNull(Box::new(self.clone())),
            TypeReference::NonNull(_) => self.clone(),
        }
    }

    pub fn nullable_type(&self) -> &TypeReference {
        match self {
            TypeReference::Named(_) => self,
            TypeReference::List(_) => self,
            TypeReference::NonNull(of) => of,
        }
    }

    pub fn is_non_null(&self) -> bool {
        matches!(self, TypeReference::NonNull(_))
    }

    pub fn is_list(&self) -> bool {
        matches!(self.nullable_type(), TypeReference::List(_))
    }

    // If the type is Named or NonNull<Named> return the inner named.
    // If the type is a List or NonNull<List> returns a matching list with nullable items.
    pub fn with_nullable_item_type(&self) -> TypeReference {
        match self {
            TypeReference::Named(_) => self.clone(),
            TypeReference::List(of) => TypeReference::List(Box::new(of.nullable_type().clone())),
            TypeReference::NonNull(of) => {
                let inner: &TypeReference = of;
                match inner {
                    TypeReference::List(_) => {
                        TypeReference::NonNull(Box::new(of.with_nullable_item_type()))
                    }
                    TypeReference::Named(_) => inner.clone(),
                    TypeReference::NonNull(_) => {
                        unreachable!("Invalid nested TypeReference::NonNull")
                    }
                }
            }
        }
    }

    pub fn list_item_type(&self) -> Option<&TypeReference> {
        match self.nullable_type() {
            TypeReference::List(of) => Some(of),
            _ => None,
        }
    }

    // Return None if the type is a List, otherwise return the inner type
    pub fn non_list_type(&self) -> Option<Type> {
        match self {
            TypeReference::List(_) => None,
            TypeReference::Named(type_) => Some(*type_),
            TypeReference::NonNull(of) => of.non_list_type(),
        }
    }
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Directive {
    pub name: DirectiveName,
    pub arguments: ArgumentDefinitions,
    pub locations: Vec<DirectiveLocation>,
    pub repeatable: bool,
    pub is_extension: bool,
    pub description: Option<StringKey>,
}

impl Named for Directive {
    type Name = DirectiveName;
    fn name(&self) -> DirectiveName {
        self.name
    }
}

#[derive(Clone, Debug)]
pub struct Scalar {
    pub name: WithLocation<StringKey>,
    pub is_extension: bool,
    pub directives: Vec<DirectiveValue>,
    pub description: Option<StringKey>,
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct Object {
    pub name: WithLocation<StringKey>,
    pub is_extension: bool,
    pub fields: Vec<FieldID>,
    pub interfaces: Vec<InterfaceID>,
    pub directives: Vec<DirectiveValue>,
    pub description: Option<StringKey>,
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct InputObject {
    pub name: WithLocation<StringKey>,
    pub fields: ArgumentDefinitions,
    pub directives: Vec<DirectiveValue>,
    pub description: Option<StringKey>,
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct Enum {
    pub name: WithLocation<StringKey>,
    pub is_extension: bool,
    pub values: Vec<EnumValue>,
    pub directives: Vec<DirectiveValue>,
    pub description: Option<StringKey>,
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct Union {
    pub name: WithLocation<StringKey>,
    pub is_extension: bool,
    pub members: Vec<ObjectID>,
    pub directives: Vec<DirectiveValue>,
    pub description: Option<StringKey>,
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct Interface {
    pub name: WithLocation<StringKey>,
    pub is_extension: bool,
    pub implementing_interfaces: Vec<InterfaceID>,
    pub implementing_objects: Vec<ObjectID>,
    pub fields: Vec<FieldID>,
    pub directives: Vec<DirectiveValue>,
    pub interfaces: Vec<InterfaceID>,
    pub description: Option<StringKey>,
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct Field {
    pub name: WithLocation<StringKey>,
    pub is_extension: bool,
    pub arguments: ArgumentDefinitions,
    pub type_: TypeReference,
    pub directives: Vec<DirectiveValue>,
    /// The type on which this field was defined. This field is (should)
    /// always be set, except for special fields such as __typename and
    /// __id, which are queryable on all types and therefore don't have
    /// a single parent type.
    pub parent_type: Option<Type>,
    pub description: Option<StringKey>,
}

pub struct Deprecation {
    pub reason: Option<StringKey>,
}

impl Field {
    pub fn deprecated(&self) -> Option<Deprecation> {
        self.directives
            .named(*DIRECTIVE_DEPRECATED)
            .map(|directive| Deprecation {
                reason: directive
                    .arguments
                    .named(*ARGUMENT_REASON)
                    .and_then(|reason| reason.value.get_string_literal()),
            })
    }
}

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Argument {
    pub name: ArgumentName,
    pub type_: TypeReference,
    pub default_value: Option<ConstantValue>,
    pub description: Option<StringKey>,
    pub directives: Vec<DirectiveValue>,
}

impl Named for Argument {
    type Name = ArgumentName;
    fn name(&self) -> ArgumentName {
        self.name
    }
}

#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct ArgumentValue {
    pub name: ArgumentName,
    pub value: ConstantValue,
}

#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct DirectiveValue {
    pub name: DirectiveName,
    pub arguments: Vec<ArgumentValue>,
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct EnumValue {
    pub value: StringKey,
    pub directives: Vec<DirectiveValue>,
}

#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ArgumentDefinitions(pub(crate) Vec<Argument>);

impl ArgumentDefinitions {
    pub fn new(arguments: Vec<Argument>) -> Self {
        Self(arguments)
    }

    pub fn named(&self, name: ArgumentName) -> Option<&Argument> {
        self.0.named(name)
    }

    pub fn contains(&self, name: StringKey) -> bool {
        self.0.iter().any(|x| x.name == ArgumentName(name))
    }

    pub fn iter(&self) -> Iter<'_, Argument> {
        self.0.iter()
    }

    pub fn is_empty(&self) -> bool {
        self.0.is_empty()
    }
}

impl fmt::Debug for ArgumentDefinitions {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.write_fmt(format_args!("{:#?}", self.0))
    }
}

impl IntoIterator for ArgumentDefinitions {
    type Item = Argument;
    type IntoIter = std::vec::IntoIter<Self::Item>;

    fn into_iter(self) -> Self::IntoIter {
        self.0.into_iter()
    }
}

pub trait TypeWithFields {
    fn fields(&self) -> &Vec<FieldID>;
    fn interfaces(&self) -> &Vec<InterfaceID>;
}

impl TypeWithFields for Interface {
    fn fields(&self) -> &Vec<FieldID> {
        &self.fields
    }

    fn interfaces(&self) -> &Vec<InterfaceID> {
        &self.interfaces
    }
}

impl TypeWithFields for Object {
    fn fields(&self) -> &Vec<FieldID> {
        &self.fields
    }

    fn interfaces(&self) -> &Vec<InterfaceID> {
        &self.interfaces
    }
}

#[allow(unused_macros)]
macro_rules! impl_named {
    ($type_name:ident) => {
        impl Named for $type_name {
            type Name = StringKey;
            fn name(&self) -> StringKey {
                self.name
            }
        }
    };
}

macro_rules! impl_named_for_with_location {
    ($type_name:ident, $name_type:ident) => {
        impl Named for $type_name {
            type Name = $name_type;
            fn name(&self) -> $name_type {
                self.name.item
            }
        }
    };
}

impl_named_for_with_location!(Object, StringKey);
impl_named_for_with_location!(Field, StringKey);
impl_named_for_with_location!(InputObject, StringKey);
impl_named_for_with_location!(Interface, StringKey);
impl_named_for_with_location!(Union, StringKey);
impl_named_for_with_location!(Scalar, StringKey);
impl_named_for_with_location!(Enum, StringKey);

impl Named for DirectiveValue {
    type Name = DirectiveName;
    fn name(&self) -> DirectiveName {
        self.name
    }
}

impl Named for ArgumentValue {
    type Name = ArgumentName;
    fn name(&self) -> ArgumentName {
        self.name
    }
}
<|endoftext|>


<commit_before>//! Module containing the DICOM Transfer Syntax data structure and related methods.
//! Similar to the DcmCodec in DCMTK, the `TransferSyntax` contains all of the necessary
//! algorithms for decoding and encoding DICOM data in a certain transfer syntax.
//!
//! This crate does not host specific transfer syntaxes. Instead, they are created in
//! other crates and registered in the global transfer syntax registry, which implements
//! [`TransferSyntaxIndex`]. For more
//! information, please see the `dicom-transfer-syntax-registry` crate.
//!
//! [`TransferSyntaxIndex`]: ./trait.TransferSyntaxIndex.html

use crate::adapters::{DynPixelRWAdapter, NeverPixelAdapter, PixelRWAdapter};
use crate::decode::basic::BasicDecoder;
use crate::decode::DecodeFrom;
use crate::encode::{EncodeTo, EncoderFor};
use std::io::{Read, Write};

pub use byteordered::Endianness;

/// A decoder with its type erased.
pub type DynDecoder<S> = Box<dyn DecodeFrom<S>>;

/// An encoder with its type erased.
pub type DynEncoder<'w, W> = Box<dyn EncodeTo<W> + 'w>;

/// A DICOM transfer syntax specifier. The data RW adapter `A` specifies
/// custom codec capabilities when required.
#[derive(Debug)]
pub struct TransferSyntax<A = DynDataRWAdapter, B = DynPixelRWAdapter> {
    /// The unique identifier of the transfer syntax.
    uid: &'static str,
    /// The name of the transfer syntax.
    name: &'static str,
    /// The byte order of data.
    byte_order: Endianness,
    /// Whether the transfer syntax mandates an explicit value representation,
    /// or the VR is implicit.
    explicit_vr: bool,
    /// The transfer syntax' requirements and implemented capabilities.
    codec: Codec<A, B>,
}

#[cfg(feature = "inventory-registry")]
// Collect transfer syntax specifiers from other crates.
inventory::collect!(TransferSyntax);

/// Trait for containers of transfer syntax specifiers.
///
/// Types implementing this trait are held responsible for populating
/// themselves with a set of transfer syntaxes, which can be fully supported,
/// partially supported, or not supported. Usually, only one implementation
/// of this trait is used for the entire program.
pub trait TransferSyntaxIndex {
    /// Obtain a DICOM transfer syntax by its respective UID.
    ///
    /// Implementations of this method should be robust to the possible
    /// presence of a trailing null characters (`\0`) in `uid`.
    fn get(&self, uid: &str) -> Option<&TransferSyntax>;
}

impl<T: ?Sized> TransferSyntaxIndex for &T
where
    T: TransferSyntaxIndex,
{
    fn get(&self, uid: &str) -> Option<&TransferSyntax> {
        (**self).get(uid)
    }
}

#[cfg(feature = "inventory-registry")]
#[macro_export]
/// Submit a transfer syntax specifier to be supported by the
/// program's runtime. This is to be used by crates wishing to provide
/// additional support for a certain transfer syntax using the
/// main transfer syntax registry.
///
/// This macro does actually "run" anything, so place it outside of a
/// function body at the root of the crate.
macro_rules! submit_transfer_syntax {
    ($ts: expr) => {
        inventory::submit! {
            ($ts).erased()
        }
    };
}

#[cfg(not(feature = "inventory-registry"))]
#[macro_export]
/// Submit a transfer syntax specifier to be supported by the
/// program's runtime. This is to be used by crates wishing to provide
/// additional support for a certain transfer syntax using the
/// main transfer syntax registry.
///
/// This macro does actually "run" anything, so place it outside of a
/// function body at the root of the crate.
///
/// Without the `inventory-registry` feature, this request is ignored.
macro_rules! submit_transfer_syntax {
    ($ts: expr) => {
        // ignore request
    };
}

/// A description and possible implementation regarding
/// the encoding and decoding requirements of a transfer syntax.
/// This is also used as a means to describe whether pixel data is encapsulated
/// and whether this implementation supports it.
#[derive(Debug, Clone, PartialEq)]
pub enum Codec<A, B> {
    /// No codec is given, nor is it required.
    None,
    /// Custom encoding and decoding of the entire data set is required, but
    /// not supported. This could be used by a stub of
    /// _Deflated Explicit VR Little Endian_, for example.
    Unsupported,
    /// Custom encoding and decoding of the pixel data set is required, but
    /// not supported. The program should still be able to parse DICOM
    /// data sets and fetch the pixel data in its encapsulated form.
    EncapsulatedPixelData,
    /// A pixel data encapsulation codec is required and provided for reading
    /// and writing pixel data.
    PixelData(B),
    /// A full, custom data set codec is required and provided.
    Dataset(A),
}

/// An alias for a transfer syntax specifier with no pixel data encapsulation
/// nor data set deflating.
pub type AdapterFreeTransferSyntax = TransferSyntax<NeverAdapter, NeverPixelAdapter>;

/// An adapter of byte read and write streams.
pub trait DataRWAdapter<R, W> {
    /// The type of the adapted reader.
    type Reader: Read;
    /// The type of the adapted writer.
    type Writer: Write;

    /// Adapt a byte reader.
    fn adapt_reader(&self, reader: R) -> Self::Reader
    where
        R: Read;

    /// Adapt a byte writer.
    fn adapt_writer(&self, writer: W) -> Self::Writer
    where
        W: Write;
}

/// Alias type for a dynamically dispatched data adapter.
pub type DynDataRWAdapter = Box<
    dyn DataRWAdapter<
            Box<dyn Read>,
            Box<dyn Write>,
            Reader = Box<dyn Read>,
            Writer = Box<dyn Write>,
        > + Send
        + Sync,
>;

impl<'a, T, R, W> DataRWAdapter<R, W> for &'a T
where
    T: DataRWAdapter<R, W>,
    R: Read,
    W: Write,
{
    type Reader = <T as DataRWAdapter<R, W>>::Reader;
    type Writer = <T as DataRWAdapter<R, W>>::Writer;

    /// Adapt a byte reader.
    fn adapt_reader(&self, reader: R) -> Self::Reader
    where
        R: Read,
    {
        (**self).adapt_reader(reader)
    }

    /// Adapt a byte writer.
    fn adapt_writer(&self, writer: W) -> Self::Writer
    where
        W: Write,
    {
        (**self).adapt_writer(writer)
    }
}

/** An immaterial type representing an adapted which is never required,
 * and as such is never instantiated. Most transfer syntaxes use this,
 * as they do not have to adapt readers and writers for encoding and decoding.
 */
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum NeverAdapter {}

impl<R, W> DataRWAdapter<R, W> for NeverAdapter {
    type Reader = Box<dyn Read>;
    type Writer = Box<dyn Write>;

    fn adapt_reader(&self, _reader: R) -> Self::Reader
    where
        R: Read,
    {
        unreachable!()
    }

    fn adapt_writer(&self, _writer: W) -> Self::Writer
    where
        W: Write,
    {
        unreachable!()
    }
}

impl<A, B> TransferSyntax<A, B> {
    /** Create a new transfer syntax descriptor.
     *
     * Note that only transfer syntax implementors are expected to construct
     * TS descriptors from scratch. For a practical usage of transfer syntaxes,
     * one should look up an existing transfer syntax registry by UID.
     */
    pub const fn new(
        uid: &'static str,
        name: &'static str,
        byte_order: Endianness,
        explicit_vr: bool,
        codec: Codec<A, B>,
    ) -> Self {
        TransferSyntax {
            uid,
            name,
            byte_order,
            explicit_vr,
            codec,
        }
    }

    /// Obtain this transfer syntax' unique identifier.
    pub const fn uid(&self) -> &'static str {
        self.uid
    }

    /// Obtain the name of this transfer syntax.
    pub const fn name(&self) -> &'static str {
        self.name
    }

    /// Obtain this transfer syntax' expected endianness.
    pub const fn endianness(&self) -> Endianness {
        self.byte_order
    }

    /// Obtain this transfer syntax' codec specification.
    pub fn codec(&self) -> &Codec<A, B> {
        &self.codec
    }

    /// Check whether this transfer syntax specifier provides a complete
    /// implementation.
    pub fn fully_supported(&self) -> bool {
        matches!(
            self.codec,
            Codec::None | Codec::Dataset(_) | Codec::PixelData(_),
        )
    }

    /// Check whether no codecs are required for this transfer syntax,
    /// meaning that a complete implementation is available
    /// and no pixel data conversion is required.
    pub fn is_codec_free(&self) -> bool {
        matches!(self.codec, Codec::None)
    }

    /// Check whether reading and writing of data sets is unsupported.
    /// If this is `true`, encoding and decoding will not be available.
    pub fn unsupported(&self) -> bool {
        matches!(self.codec, Codec::Unsupported)
    }

    /// Check whether reading and writing the pixel data is unsupported.
    /// If this is `true`, encoding and decoding of the data set will still
    /// be possible, but the pixel data will only be available in its
    /// encapsulated form.
    pub fn unsupported_pixel_encapsulation(&self) -> bool {
        matches!(
            self.codec,
            Codec::Unsupported | Codec::EncapsulatedPixelData
        )
    }

    /// Retrieve the appropriate data element decoder for this transfer syntax.
    /// Can yield none if decoding is not supported.
    ///
    /// The resulting decoder does not consider pixel data encapsulation or
    /// data set compression rules. This means that the consumer of this method
    /// needs to adapt the reader before using the decoder.
    pub fn decoder<'s>(&self) -> Option<DynDecoder<dyn Read + 's>> {
        self.decoder_for()
    }

    /// Retrieve the appropriate data element decoder for this transfer syntax
    /// and given reader type (this method is not object safe).
    /// Can yield none if decoding is not supported.
    ///
    /// The resulting decoder does not consider pixel data encapsulation or
    /// data set compression rules. This means that the consumer of this method
    /// needs to adapt the reader before using the decoder.
    pub fn decoder_for<S>(&self) -> Option<DynDecoder<S>>
    where
        Self: Sized,
        S: ?Sized + Read,
    {
        match (self.byte_order, self.explicit_vr) {
            (Endianness::Little, false) => Some(Box::new(
                implicit_le::ImplicitVRLittleEndianDecoder::default(),
            )),
            (Endianness::Little, true) => Some(Box::new(
                explicit_le::ExplicitVRLittleEndianDecoder::default(),
            )),
            (Endianness::Big, true) => {
                Some(Box::new(explicit_be::ExplicitVRBigEndianDecoder::default()))
            }
            _ => None,
        }
    }

    /// Retrieve the appropriate data element encoder for this transfer syntax.
    /// Can yield none if encoding is not supported. The resulting encoder does not
    /// consider pixel data encapsulation or data set compression rules.
    pub fn encoder<'w>(&self) -> Option<DynEncoder<'w, dyn Write + 'w>> {
        self.encoder_for()
    }

    /// Retrieve the appropriate data element encoder for this transfer syntax
    /// and the given writer type (this method is not object safe).
    /// Can yield none if encoding is not supported. The resulting encoder does not
    /// consider pixel data encapsulation or data set compression rules.
    pub fn encoder_for<'w, W: 'w>(&self) -> Option<DynEncoder<'w, W>>
    where
        Self: Sized,
        W: ?Sized + Write,
    {
        match (self.byte_order, self.explicit_vr) {
            (Endianness::Little, false) => Some(Box::new(EncoderFor::new(
                implicit_le::ImplicitVRLittleEndianEncoder::default(),
            ))),
            (Endianness::Little, true) => Some(Box::new(EncoderFor::new(
                explicit_le::ExplicitVRLittleEndianEncoder::default(),
            ))),
            (Endianness::Big, true) => Some(Box::new(EncoderFor::new(
                explicit_be::ExplicitVRBigEndianEncoder::default(),
            ))),
            _ => None,
        }
    }

    /// Obtain a dynamic basic decoder, based on this transfer syntax' expected endianness.
    pub fn basic_decoder(&self) -> BasicDecoder {
        BasicDecoder::from(self.endianness())
    }

    /// Type-erase the pixel data or data set codec.
    pub fn erased(self) -> TransferSyntax
    where
        A: Send + Sync + 'static,
        A: DataRWAdapter<
            Box<dyn Read>,
            Box<dyn Write>,
            Reader = Box<dyn Read>,
            Writer = Box<dyn Write>,
        >,
        B: Send + Sync + 'static,
        B: PixelRWAdapter,
    {
        let codec = match self.codec {
            Codec::Dataset(a) => Codec::Dataset(Box::new(a) as DynDataRWAdapter),
            Codec::PixelData(b) => Codec::PixelData(Box::new(b) as DynPixelRWAdapter),
            Codec::EncapsulatedPixelData => Codec::EncapsulatedPixelData,
            Codec::Unsupported => Codec::Unsupported,
            Codec::None => Codec::None,
        };

        TransferSyntax {
            uid: self.uid,
            name: self.name,
            byte_order: self.byte_order,
            explicit_vr: self.explicit_vr,
            codec,
        }
    }
}
<commit_msg>Update imports in encoding::transfer_syntax<commit_after>//! Module containing the DICOM Transfer Syntax data structure and related methods.
//! Similar to the DcmCodec in DCMTK, the `TransferSyntax` contains all of the necessary
//! algorithms for decoding and encoding DICOM data in a certain transfer syntax.
//!
//! This crate does not host specific transfer syntaxes. Instead, they are created in
//! other crates and registered in the global transfer syntax registry, which implements
//! [`TransferSyntaxIndex`]. For more
//! information, please see the `dicom-transfer-syntax-registry` crate.
//!
//! [`TransferSyntaxIndex`]: ./trait.TransferSyntaxIndex.html

use crate::adapters::{DynPixelRWAdapter, NeverPixelAdapter, PixelRWAdapter};
use crate::decode::{
    basic::BasicDecoder, explicit_be::ExplicitVRBigEndianDecoder,
    explicit_le::ExplicitVRLittleEndianDecoder, implicit_le::ImplicitVRLittleEndianDecoder,
    DecodeFrom,
};
use crate::encode::{
    explicit_be::ExplicitVRBigEndianEncoder, explicit_le::ExplicitVRLittleEndianEncoder,
    implicit_le::ImplicitVRLittleEndianEncoder, EncodeTo, EncoderFor,
};
use std::io::{Read, Write};

pub use byteordered::Endianness;

/// A decoder with its type erased.
pub type DynDecoder<S> = Box<dyn DecodeFrom<S>>;

/// An encoder with its type erased.
pub type DynEncoder<'w, W> = Box<dyn EncodeTo<W> + 'w>;

/// A DICOM transfer syntax specifier. The data RW adapter `A` specifies
/// custom codec capabilities when required.
#[derive(Debug)]
pub struct TransferSyntax<A = DynDataRWAdapter, B = DynPixelRWAdapter> {
    /// The unique identifier of the transfer syntax.
    uid: &'static str,
    /// The name of the transfer syntax.
    name: &'static str,
    /// The byte order of data.
    byte_order: Endianness,
    /// Whether the transfer syntax mandates an explicit value representation,
    /// or the VR is implicit.
    explicit_vr: bool,
    /// The transfer syntax' requirements and implemented capabilities.
    codec: Codec<A, B>,
}

#[cfg(feature = "inventory-registry")]
// Collect transfer syntax specifiers from other crates.
inventory::collect!(TransferSyntax);

/// Trait for containers of transfer syntax specifiers.
///
/// Types implementing this trait are held responsible for populating
/// themselves with a set of transfer syntaxes, which can be fully supported,
/// partially supported, or not supported. Usually, only one implementation
/// of this trait is used for the entire program.
pub trait TransferSyntaxIndex {
    /// Obtain a DICOM transfer syntax by its respective UID.
    ///
    /// Implementations of this method should be robust to the possible
    /// presence of a trailing null characters (`\0`) in `uid`.
    fn get(&self, uid: &str) -> Option<&TransferSyntax>;
}

impl<T: ?Sized> TransferSyntaxIndex for &T
where
    T: TransferSyntaxIndex,
{
    fn get(&self, uid: &str) -> Option<&TransferSyntax> {
        (**self).get(uid)
    }
}

#[cfg(feature = "inventory-registry")]
#[macro_export]
/// Submit a transfer syntax specifier to be supported by the
/// program's runtime. This is to be used by crates wishing to provide
/// additional support for a certain transfer syntax using the
/// main transfer syntax registry.
///
/// This macro does actually "run" anything, so place it outside of a
/// function body at the root of the crate.
macro_rules! submit_transfer_syntax {
    ($ts: expr) => {
        inventory::submit! {
            ($ts).erased()
        }
    };
}

#[cfg(not(feature = "inventory-registry"))]
#[macro_export]
/// Submit a transfer syntax specifier to be supported by the
/// program's runtime. This is to be used by crates wishing to provide
/// additional support for a certain transfer syntax using the
/// main transfer syntax registry.
///
/// This macro does actually "run" anything, so place it outside of a
/// function body at the root of the crate.
///
/// Without the `inventory-registry` feature, this request is ignored.
macro_rules! submit_transfer_syntax {
    ($ts: expr) => {
        // ignore request
    };
}

/// A description and possible implementation regarding
/// the encoding and decoding requirements of a transfer syntax.
/// This is also used as a means to describe whether pixel data is encapsulated
/// and whether this implementation supports it.
#[derive(Debug, Clone, PartialEq)]
pub enum Codec<A, B> {
    /// No codec is given, nor is it required.
    None,
    /// Custom encoding and decoding of the entire data set is required, but
    /// not supported. This could be used by a stub of
    /// _Deflated Explicit VR Little Endian_, for example.
    Unsupported,
    /// Custom encoding and decoding of the pixel data set is required, but
    /// not supported. The program should still be able to parse DICOM
    /// data sets and fetch the pixel data in its encapsulated form.
    EncapsulatedPixelData,
    /// A pixel data encapsulation codec is required and provided for reading
    /// and writing pixel data.
    PixelData(B),
    /// A full, custom data set codec is required and provided.
    Dataset(A),
}

/// An alias for a transfer syntax specifier with no pixel data encapsulation
/// nor data set deflating.
pub type AdapterFreeTransferSyntax = TransferSyntax<NeverAdapter, NeverPixelAdapter>;

/// An adapter of byte read and write streams.
pub trait DataRWAdapter<R, W> {
    /// The type of the adapted reader.
    type Reader: Read;
    /// The type of the adapted writer.
    type Writer: Write;

    /// Adapt a byte reader.
    fn adapt_reader(&self, reader: R) -> Self::Reader
    where
        R: Read;

    /// Adapt a byte writer.
    fn adapt_writer(&self, writer: W) -> Self::Writer
    where
        W: Write;
}

/// Alias type for a dynamically dispatched data adapter.
pub type DynDataRWAdapter = Box<
    dyn DataRWAdapter<
            Box<dyn Read>,
            Box<dyn Write>,
            Reader = Box<dyn Read>,
            Writer = Box<dyn Write>,
        > + Send
        + Sync,
>;

impl<'a, T, R, W> DataRWAdapter<R, W> for &'a T
where
    T: DataRWAdapter<R, W>,
    R: Read,
    W: Write,
{
    type Reader = <T as DataRWAdapter<R, W>>::Reader;
    type Writer = <T as DataRWAdapter<R, W>>::Writer;

    /// Adapt a byte reader.
    fn adapt_reader(&self, reader: R) -> Self::Reader
    where
        R: Read,
    {
        (**self).adapt_reader(reader)
    }

    /// Adapt a byte writer.
    fn adapt_writer(&self, writer: W) -> Self::Writer
    where
        W: Write,
    {
        (**self).adapt_writer(writer)
    }
}

/** An immaterial type representing an adapted which is never required,
 * and as such is never instantiated. Most transfer syntaxes use this,
 * as they do not have to adapt readers and writers for encoding and decoding.
 */
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum NeverAdapter {}

impl<R, W> DataRWAdapter<R, W> for NeverAdapter {
    type Reader = Box<dyn Read>;
    type Writer = Box<dyn Write>;

    fn adapt_reader(&self, _reader: R) -> Self::Reader
    where
        R: Read,
    {
        unreachable!()
    }

    fn adapt_writer(&self, _writer: W) -> Self::Writer
    where
        W: Write,
    {
        unreachable!()
    }
}

impl<A, B> TransferSyntax<A, B> {
    /** Create a new transfer syntax descriptor.
     *
     * Note that only transfer syntax implementors are expected to construct
     * TS descriptors from scratch. For a practical usage of transfer syntaxes,
     * one should look up an existing transfer syntax registry by UID.
     */
    pub const fn new(
        uid: &'static str,
        name: &'static str,
        byte_order: Endianness,
        explicit_vr: bool,
        codec: Codec<A, B>,
    ) -> Self {
        TransferSyntax {
            uid,
            name,
            byte_order,
            explicit_vr,
            codec,
        }
    }

    /// Obtain this transfer syntax' unique identifier.
    pub const fn uid(&self) -> &'static str {
        self.uid
    }

    /// Obtain the name of this transfer syntax.
    pub const fn name(&self) -> &'static str {
        self.name
    }

    /// Obtain this transfer syntax' expected endianness.
    pub const fn endianness(&self) -> Endianness {
        self.byte_order
    }

    /// Obtain this transfer syntax' codec specification.
    pub fn codec(&self) -> &Codec<A, B> {
        &self.codec
    }

    /// Check whether this transfer syntax specifier provides a complete
    /// implementation.
    pub fn fully_supported(&self) -> bool {
        matches!(
            self.codec,
            Codec::None | Codec::Dataset(_) | Codec::PixelData(_),
        )
    }

    /// Check whether no codecs are required for this transfer syntax,
    /// meaning that a complete implementation is available
    /// and no pixel data conversion is required.
    pub fn is_codec_free(&self) -> bool {
        matches!(self.codec, Codec::None)
    }

    /// Check whether reading and writing of data sets is unsupported.
    /// If this is `true`, encoding and decoding will not be available.
    pub fn unsupported(&self) -> bool {
        matches!(self.codec, Codec::Unsupported)
    }

    /// Check whether reading and writing the pixel data is unsupported.
    /// If this is `true`, encoding and decoding of the data set will still
    /// be possible, but the pixel data will only be available in its
    /// encapsulated form.
    pub fn unsupported_pixel_encapsulation(&self) -> bool {
        matches!(
            self.codec,
            Codec::Unsupported | Codec::EncapsulatedPixelData
        )
    }

    /// Retrieve the appropriate data element decoder for this transfer syntax.
    /// Can yield none if decoding is not supported.
    ///
    /// The resulting decoder does not consider pixel data encapsulation or
    /// data set compression rules. This means that the consumer of this method
    /// needs to adapt the reader before using the decoder.
    pub fn decoder<'s>(&self) -> Option<DynDecoder<dyn Read + 's>> {
        self.decoder_for()
    }

    /// Retrieve the appropriate data element decoder for this transfer syntax
    /// and given reader type (this method is not object safe).
    /// Can yield none if decoding is not supported.
    ///
    /// The resulting decoder does not consider pixel data encapsulation or
    /// data set compression rules. This means that the consumer of this method
    /// needs to adapt the reader before using the decoder.
    pub fn decoder_for<S>(&self) -> Option<DynDecoder<S>>
    where
        Self: Sized,
        S: ?Sized + Read,
    {
        match (self.byte_order, self.explicit_vr) {
            (Endianness::Little, false) => Some(Box::new(ImplicitVRLittleEndianDecoder::default())),
            (Endianness::Little, true) => Some(Box::new(ExplicitVRLittleEndianDecoder::default())),
            (Endianness::Big, true) => Some(Box::new(ExplicitVRBigEndianDecoder::default())),
            _ => None,
        }
    }

    /// Retrieve the appropriate data element encoder for this transfer syntax.
    /// Can yield none if encoding is not supported. The resulting encoder does not
    /// consider pixel data encapsulation or data set compression rules.
    pub fn encoder<'w>(&self) -> Option<DynEncoder<'w, dyn Write + 'w>> {
        self.encoder_for()
    }

    /// Retrieve the appropriate data element encoder for this transfer syntax
    /// and the given writer type (this method is not object safe).
    /// Can yield none if encoding is not supported. The resulting encoder does not
    /// consider pixel data encapsulation or data set compression rules.
    pub fn encoder_for<'w, W: 'w>(&self) -> Option<DynEncoder<'w, W>>
    where
        Self: Sized,
        W: ?Sized + Write,
    {
        match (self.byte_order, self.explicit_vr) {
            (Endianness::Little, false) => Some(Box::new(EncoderFor::new(
                ImplicitVRLittleEndianEncoder::default(),
            ))),
            (Endianness::Little, true) => Some(Box::new(EncoderFor::new(
                ExplicitVRLittleEndianEncoder::default(),
            ))),
            (Endianness::Big, true) => Some(Box::new(EncoderFor::new(
                ExplicitVRBigEndianEncoder::default(),
            ))),
            _ => None,
        }
    }

    /// Obtain a dynamic basic decoder, based on this transfer syntax' expected endianness.
    pub fn basic_decoder(&self) -> BasicDecoder {
        BasicDecoder::from(self.endianness())
    }

    /// Type-erase the pixel data or data set codec.
    pub fn erased(self) -> TransferSyntax
    where
        A: Send + Sync + 'static,
        A: DataRWAdapter<
            Box<dyn Read>,
            Box<dyn Write>,
            Reader = Box<dyn Read>,
            Writer = Box<dyn Write>,
        >,
        B: Send + Sync + 'static,
        B: PixelRWAdapter,
    {
        let codec = match self.codec {
            Codec::Dataset(a) => Codec::Dataset(Box::new(a) as DynDataRWAdapter),
            Codec::PixelData(b) => Codec::PixelData(Box::new(b) as DynPixelRWAdapter),
            Codec::EncapsulatedPixelData => Codec::EncapsulatedPixelData,
            Codec::Unsupported => Codec::Unsupported,
            Codec::None => Codec::None,
        };

        TransferSyntax {
            uid: self.uid,
            name: self.name,
            byte_order: self.byte_order,
            explicit_vr: self.explicit_vr,
            codec,
        }
    }
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::io;
use std::rc::{Rc, Weak};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use mio::{Event, PollOpt, Ready, Token};
use mio::net::UdpSocket;

use super::client::Client;
use super::connection::{self, Connection, ConnectionId};
use super::datagram_buffer::DatagramBuffer;
use super::ipv4_packet::{IPv4Packet, MAX_PACKET_LENGTH};
use super::packetizer::Packetizer;
use super::selector::Selector;

const TAG: &'static str = "UDPConnection";

pub struct UDPConnection {
    id: ConnectionId,
    client: Weak<RefCell<Client>>,
    socket: UdpSocket,
    token: Token,
    client_to_network: DatagramBuffer,
    network_to_client: Packetizer,
    closed: bool,
}

impl UDPConnection {
    pub fn new(selector: &mut Selector, id: ConnectionId, client: Weak<RefCell<Client>>, reference_packet: &IPv4Packet) -> io::Result<Rc<RefCell<Self>>> {
        let socket = UDPConnection::create_socket(&id)?;
        let raw: &[u8] = reference_packet.raw();
        let ipv4_header = reference_packet.ipv4_header().clone();
        let transport_header = reference_packet.transport_header().as_ref().unwrap().clone();
        let rc = Rc::new(RefCell::new(Self {
            id: id,
            client: client,
            socket: socket,
            token: Token(0), // default value, will be set afterwards
            client_to_network: DatagramBuffer::new(4 * MAX_PACKET_LENGTH),
            network_to_client: Packetizer::new(raw, ipv4_header, transport_header),
            closed: false,
        }));

        {
            let rc_clone = rc.clone();
            let handler = move |selector: &mut Selector, ready| {
                let mut self_ref = rc_clone.borrow_mut();
                self_ref.on_ready(selector, ready);
            };
            let mut self_ref = rc.borrow_mut();
            let token = selector.register(&self_ref.socket, handler, Ready::readable(), PollOpt::level())?;
            self_ref.token = token;
        }
        Ok(rc)
    }

    fn create_socket(id: &ConnectionId) -> io::Result<UdpSocket> {
        let autobind_addr = SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), 0);
        let udp_socket = UdpSocket::bind(&autobind_addr)?;
        let rewritten_destination = connection::rewritten_destination(id.destination_ip(), id.destination_port()).into();
        udp_socket.connect(rewritten_destination)?;
        Ok(udp_socket)
    }

    fn close(&mut self, selector: &mut Selector) {
        self.disconnect();

        // route is embedded in router which is embedded in client: the client necessarily exists
        let client_rc = self.client.upgrade().expect("expected client not found");
        let mut client = client_rc.borrow_mut();
        client.router().remove(&self.id);
    }

    fn process_send(&mut self, selector: &mut Selector) {
        if let Err(_) = self.write() {
            error!(target: TAG, "Cannot write");
            self.close(selector);
        }
    }

    fn process_receive(&mut self, selector: &mut Selector) {
        // TODO
    }

    fn update_interests(&mut self, selector: &mut Selector) -> io::Result<()> {
        let mut ready = Ready::empty();
        if self.may_read() {
            ready = Ready::readable();
        }
        if self.may_write() {
            ready = ready | Ready::writable();
        }
        selector.reregister(&self.socket, self.token, ready, PollOpt::level())
    }

    fn read(&mut self) -> io::Result<()> {
        let packet = self.network_to_client.packetize(&mut self.socket)?;
        // TODO
        Ok(())
    }

    fn write(&mut self) -> io::Result<()> {
        self.client_to_network.write_to(&mut self.socket)?;
        Ok(())
    }

    fn may_read(&self) -> bool {
        // TODO
        true
    }

    fn may_write(&self) -> bool {
        !self.client_to_network.is_empty()
    }

    fn on_ready(&mut self, selector: &mut Selector, event: Event) {
        assert!(!self.closed);
        let ready = event.readiness();
        if ready.is_writable() {
            self.process_send(selector);
        }
        if !self.closed && ready.is_readable() {
            self.process_receive(selector);
        }
        if !self.closed {
            self.update_interests(selector);
        }
    }
}

impl Connection for UDPConnection {
    fn id(&self) -> &ConnectionId {
        &self.id
    }

    fn send_to_network(&mut self, selector: &mut Selector, ipv4_packet: &IPv4Packet) {
        // TODO
    }

    fn disconnect(&mut self) {
        // TODO
    }

    fn is_expired(&self) -> bool {
        // TODO
        false
    }
}
<commit_msg>Introduce pending packet for UDPConnection<commit_after>use std::cell::RefCell;
use std::io;
use std::rc::{Rc, Weak};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use mio::{Event, PollOpt, Ready, Token};
use mio::net::UdpSocket;

use super::client::Client;
use super::connection::{self, Connection, ConnectionId};
use super::datagram_buffer::DatagramBuffer;
use super::ipv4_packet::{IPv4Packet, MAX_PACKET_LENGTH};
use super::packetizer::Packetizer;
use super::selector::Selector;

const TAG: &'static str = "UDPConnection";

pub struct UDPConnection {
    id: ConnectionId,
    client: Weak<RefCell<Client>>,
    socket: UdpSocket,
    token: Token,
    client_to_network: DatagramBuffer,
    network_to_client: Packetizer,
    pending_packet_for_client: Option<Box<[u8]>>, // used when the client buffer is full, should be rare
    closed: bool,
}

impl UDPConnection {
    pub fn new(selector: &mut Selector, id: ConnectionId, client: Weak<RefCell<Client>>, reference_packet: &IPv4Packet) -> io::Result<Rc<RefCell<Self>>> {
        let socket = UDPConnection::create_socket(&id)?;
        let raw: &[u8] = reference_packet.raw();
        let ipv4_header = reference_packet.ipv4_header().clone();
        let transport_header = reference_packet.transport_header().as_ref().unwrap().clone();
        let rc = Rc::new(RefCell::new(Self {
            id: id,
            client: client,
            socket: socket,
            token: Token(0), // default value, will be set afterwards
            client_to_network: DatagramBuffer::new(4 * MAX_PACKET_LENGTH),
            network_to_client: Packetizer::new(raw, ipv4_header, transport_header),
            pending_packet_for_client: None,
            closed: false,
        }));

        {
            let rc_clone = rc.clone();
            let handler = move |selector: &mut Selector, ready| {
                let mut self_ref = rc_clone.borrow_mut();
                self_ref.on_ready(selector, ready);
            };
            let mut self_ref = rc.borrow_mut();
            let token = selector.register(&self_ref.socket, handler, Ready::readable(), PollOpt::level())?;
            self_ref.token = token;
        }
        Ok(rc)
    }

    fn create_socket(id: &ConnectionId) -> io::Result<UdpSocket> {
        let autobind_addr = SocketAddr::new(Ipv4Addr::new(0, 0, 0, 0).into(), 0);
        let udp_socket = UdpSocket::bind(&autobind_addr)?;
        let rewritten_destination = connection::rewritten_destination(id.destination_ip(), id.destination_port()).into();
        udp_socket.connect(rewritten_destination)?;
        Ok(udp_socket)
    }

    fn close(&mut self, selector: &mut Selector) {
        self.disconnect();

        // route is embedded in router which is embedded in client: the client necessarily exists
        let client_rc = self.client.upgrade().expect("expected client not found");
        let mut client = client_rc.borrow_mut();
        client.router().remove(&self.id);
    }

    fn process_send(&mut self, selector: &mut Selector) {
        if let Err(err) = self.write() {
            error!(target: TAG, "Cannot write: {}", err);
            self.close(selector);
        }
    }

    fn process_receive(&mut self, selector: &mut Selector) {
        if let Err(err) = self.read() {
            error!(target: TAG, "Cannot read: {}", err);
            self.close(selector);
        }
        // TODO push to client
    }

    fn update_interests(&mut self, selector: &mut Selector) -> io::Result<()> {
        let mut ready = Ready::empty();
        if self.may_read() {
            ready = Ready::readable();
        }
        if self.may_write() {
            ready = ready | Ready::writable();
        }
        selector.reregister(&self.socket, self.token, ready, PollOpt::level())
    }

    fn read(&mut self) -> io::Result<()> {
        assert!(self.pending_packet_for_client.is_none());
        let packet = self.network_to_client.packetize(&mut self.socket)?;
        // TODO
        Ok(())
    }

    fn write(&mut self) -> io::Result<()> {
        self.client_to_network.write_to(&mut self.socket)?;
        Ok(())
    }

    fn may_read(&self) -> bool {
        // TODO
        true
    }

    fn may_write(&self) -> bool {
        !self.client_to_network.is_empty()
    }

    fn on_ready(&mut self, selector: &mut Selector, event: Event) {
        assert!(!self.closed);
        let ready = event.readiness();
        if ready.is_writable() {
            self.process_send(selector);
        }
        if !self.closed && ready.is_readable() {
            self.process_receive(selector);
        }
        if !self.closed {
            self.update_interests(selector);
        }
    }
}

impl Connection for UDPConnection {
    fn id(&self) -> &ConnectionId {
        &self.id
    }

    fn send_to_network(&mut self, selector: &mut Selector, ipv4_packet: &IPv4Packet) {
        // TODO
    }

    fn disconnect(&mut self) {
        // TODO
    }

    fn is_expired(&self) -> bool {
        // TODO
        false
    }
}
<|endoftext|>


<commit_before>//! This example will showcase one way on how to extend Serentiy with a
//! time-scheduler and an event-trigger-system.
//! We will create a remind-me command that will send a message after a
//! a demanded amount of time. Once the message has been sent, the user can
//! react to it, triggering an event to send another message.
use std::{collections::HashSet, env, hash::{BuildHasher, Hash, Hasher},
    sync::Arc,
};
use serenity::{
    prelude::*,
    framework::standard::{
        Args, CommandResult, CommandGroup,
        DispatchError, HelpOptions, help_commands, StandardFramework,
        macros::{command, group, help},
    },
    http::Http,
    model::prelude::*,
};
// We will use this crate as event dispatcher.
use hey_listen::sync::{ParallelDispatcher as Dispatcher,
    ParallelDispatcherRequest as DispatcherRequest};
// And this crate to schedule our tasks.
use white_rabbit::{Utc, Scheduler, DateResult, Duration};

// This enum represents possible events a listener might wait for.
// In this case, we want to dispatch an event when a reaction is added.
// Serenity's event-enum is not suitable for this.
// First it offers too many variants we do not need, but most importantly,
// it lacks the `Default`-trait which makes sense
// as the enum-fields have no clear logical default value. But without it,
// constructing mock-variants becomes difficult.
//
// As a result, we make our own slick event-enum!
#[derive(Clone)]
enum DispatchEvent {
    ReactEvent(MessageId, UserId),
}

// We need to implement equality for our enum.
// One could test variants only. In this case, we want to know who reacted
// on which message.
impl PartialEq for DispatchEvent {
    fn eq(&self, other: &DispatchEvent) -> bool {
        match (self, other) {
            (DispatchEvent::ReactEvent(self_message_id, self_user_id),
            DispatchEvent::ReactEvent(other_message_id, other_user_id)) => {
                self_message_id == other_message_id &&
                self_user_id == other_user_id
            }
        }
    }
}

impl Eq for DispatchEvent {}

// See following Clippy-lint:
// https://rust-lang.github.io/rust-clippy/master/index.html#derive_hash_xor_eq
impl Hash for DispatchEvent {
    fn hash<H: Hasher>(&self, state: &mut H) {
        match self {
            DispatchEvent::ReactEvent(msg_id, user_id) => {
                msg_id.hash(state);
                user_id.hash(state);
            }
        }
    }
}

struct DispatcherKey;
impl TypeMapKey for DispatcherKey {
    type Value = Arc<RwLock<Dispatcher<DispatchEvent>>>;
}

struct SchedulerKey;
impl TypeMapKey for SchedulerKey {
    type Value = Arc<RwLock<Scheduler>>;
}

struct Handler;
impl EventHandler for Handler {
    // We want to dispatch an event whenever a new reaction has been added.
    fn reaction_add(&self, context: Context, reaction: Reaction) {
        let dispatcher = {
            let mut context = context.data.write();
            context.get_mut::<DispatcherKey>().expect("Expected Dispatcher.").clone()
        };

        dispatcher.write().dispatch_event(
            &DispatchEvent::ReactEvent(reaction.message_id, reaction.user_id));
    }
}

group!({
    name: "remind_me",
    options: {
        prefixes: ["rm", "reminder"],
    },
    commands: [set_reminder],
});

#[help]
fn my_help(
    context: &mut Context,
    msg: &Message,
    args: Args,
    help_options: &'static HelpOptions,
    groups: &[&'static CommandGroup],
    owners: HashSet<UserId, impl BuildHasher>
) -> CommandResult {
    help_commands::with_embeds(context, msg, args, &help_options, groups, owners)
}

fn main() {
    // Configure the client with your Discord bot token in the environment.
    let token = env::var("DISCORD_TOKEN").expect(
        "Expected a token in the environment",
    );
    let mut client = Client::new(&token, Handler)
        .expect("Err creating client");

    {
        let mut data = client.data.write();
        // We create a new scheduler with 4 internal threads. Why 4? It really
        // is just an arbitrary number, you are often better setting this
        // based on your CPU.
        // When a task is due, a thread from the threadpool will be used to
        // avoid blocking the scheduler thread.
        let scheduler = Scheduler::new(4);
        let scheduler = Arc::new(RwLock::new(scheduler));

        let mut dispatcher: Dispatcher<DispatchEvent> = Dispatcher::default();
        // Once receiving an event to dispatch, the amount of threads
        // set via `num_threads` will dispatch in parallel.
        dispatcher.num_threads(4).expect("Could not construct threadpool");

        data.insert::<DispatcherKey>(Arc::new(RwLock::new(dispatcher)));
        data.insert::<SchedulerKey>(scheduler);
    }

    // We will fetch your bot's id.
    let bot_id = match client.cache_and_http.http.get_current_application_info() {
        Ok(info) => {
            info.id
        },
        Err(why) => panic!("Could not access application info: {:?}", why),
    };

    client.with_framework(
        // Configures the client, allowing for options to mutate how the
        // framework functions.
        StandardFramework::new()
        .configure(|c| c
            .with_whitespace(true)
            .on_mention(Some(bot_id))
            .prefix("~")
            .delimiters(vec![", ", ","]))
        .on_dispatch_error(|ctx, msg, error| {
            if let DispatchError::Ratelimited(seconds) = error {
                let _ = msg.channel_id.say(&ctx.http, &format!("Try this again in {} seconds.", seconds));
            }
        })
        .after(|_ctx, _msg, cmd_name, error| {

        if let Err(why) = error {
            println!("Error in {}: {:?}", cmd_name, why);
        }
    })
        .help(&MY_HELP)
        .group(&REMIND_ME_GROUP)
    );

    if let Err(why) = client.start() {
        println!("Client error: {:?}", why);
    }
}

// Just a helper-function for creating the closure we want to use as listener.
// It saves us from writing the same trigger twice for repeated and non-repeated
// tasks (see remind-me command below).
fn thanks_for_reacting(http: Arc<Http>, channel: ChannelId) ->
    Box<Fn(&DispatchEvent) -> Option<DispatcherRequest> + Send + Sync> {

    Box::new(move |_| {
        if let Err(why) = channel.say(&http, "Thanks for reacting!") {
            println!("Could not send message: {:?}", why);
        }

        Some(DispatcherRequest::StopListening)
    })
}

#[command]
#[aliases("add")]
fn set_reminder(context: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
    // It might be smart to set a moderately high minimum value for `time`
    // to avoid abuse like tasks that repeat every 100ms, especially since
    // channels have send-message rate limits.
    let time: u64 = args.single()?;
    let repeat: bool = args.single()?;
    let args = args.rest().to_string();

    let scheduler = {
        let mut context = context.data.write();
        context.get_mut::<SchedulerKey>().expect("Expected Scheduler.").clone()
    };

    let dispatcher = {
        let mut context = context.data.write();
        context.get_mut::<DispatcherKey>().expect("Expected Dispatcher.").clone()
    };

    let http = context.http.clone();
    let msg = msg.clone();

    let mut scheduler = scheduler.write();

    // First, we check if the user wants a repeated task or not.
    if repeat {
        // Chrono's duration can also be negative
        // and therefore we cast to `i64`.
        scheduler.add_task_duration(Duration::milliseconds(time as i64), move |_| {
            let bot_msg = match msg.channel_id.say(&http, &args) {
                Ok(msg) => msg,
                // We could not send the message, thus we will try sending it
                // again in five seconds.
                // It might be wise to keep a counter for maximum tries.
                // If the channel got deleted, trying to send a message will
                // always fail.
                Err(why) => {
                    println!("Error sending message: {:?}.", why);

                    return DateResult::Repeat(
                        Utc::now() + Duration::milliseconds(5000))
                },
            };

            let http = http.clone();

            // We add a function to dispatch for a certain event.
            dispatcher.write()
                .add_fn(DispatchEvent::ReactEvent(bot_msg.id, msg.author.id),
                    // The `thanks_for_reacting`-function creates a function
                    // to schedule.
                    thanks_for_reacting(http, bot_msg.channel_id));

            // We return that our date shall happen again, therefore we need
            // to tell when this shall be.
            DateResult::Repeat(Utc::now() + Duration::milliseconds(time as i64))
        });
    } else {
        // Pretty much identical with the `true`-case except for the returned
        // variant.
        scheduler.add_task_duration(Duration::milliseconds(time as i64), move |_| {
            let bot_msg = match msg.channel_id.say(&http, &args) {
                Ok(msg) => msg,
                Err(why) => {
                    println!("Error sending message: {:?}.", why);

                    return DateResult::Repeat(
                        Utc::now() + Duration::milliseconds(5000)
                    )
                },
            };
            let http = http.clone();

            dispatcher.write()
                .add_fn(DispatchEvent::ReactEvent(bot_msg.id, msg.author.id),
                    thanks_for_reacting(http, bot_msg.channel_id));

            // The task is done and that's it, we do not to repeat it.
            DateResult::Done
        });
    };

    Ok(())
}
<commit_msg>Remove unneeded generic parameter<commit_after>//! This example will showcase one way on how to extend Serentiy with a
//! time-scheduler and an event-trigger-system.
//! We will create a remind-me command that will send a message after a
//! a demanded amount of time. Once the message has been sent, the user can
//! react to it, triggering an event to send another message.
use std::{collections::HashSet, env, hash::{Hash, Hasher},
    sync::Arc,
};
use serenity::{
    prelude::*,
    framework::standard::{
        Args, CommandResult, CommandGroup,
        DispatchError, HelpOptions, help_commands, StandardFramework,
        macros::{command, group, help},
    },
    http::Http,
    model::prelude::*,
};
// We will use this crate as event dispatcher.
use hey_listen::sync::{ParallelDispatcher as Dispatcher,
    ParallelDispatcherRequest as DispatcherRequest};
// And this crate to schedule our tasks.
use white_rabbit::{Utc, Scheduler, DateResult, Duration};

// This enum represents possible events a listener might wait for.
// In this case, we want to dispatch an event when a reaction is added.
// Serenity's event-enum is not suitable for this.
// First it offers too many variants we do not need, but most importantly,
// it lacks the `Default`-trait which makes sense
// as the enum-fields have no clear logical default value. But without it,
// constructing mock-variants becomes difficult.
//
// As a result, we make our own slick event-enum!
#[derive(Clone)]
enum DispatchEvent {
    ReactEvent(MessageId, UserId),
}

// We need to implement equality for our enum.
// One could test variants only. In this case, we want to know who reacted
// on which message.
impl PartialEq for DispatchEvent {
    fn eq(&self, other: &DispatchEvent) -> bool {
        match (self, other) {
            (DispatchEvent::ReactEvent(self_message_id, self_user_id),
            DispatchEvent::ReactEvent(other_message_id, other_user_id)) => {
                self_message_id == other_message_id &&
                self_user_id == other_user_id
            }
        }
    }
}

impl Eq for DispatchEvent {}

// See following Clippy-lint:
// https://rust-lang.github.io/rust-clippy/master/index.html#derive_hash_xor_eq
impl Hash for DispatchEvent {
    fn hash<H: Hasher>(&self, state: &mut H) {
        match self {
            DispatchEvent::ReactEvent(msg_id, user_id) => {
                msg_id.hash(state);
                user_id.hash(state);
            }
        }
    }
}

struct DispatcherKey;
impl TypeMapKey for DispatcherKey {
    type Value = Arc<RwLock<Dispatcher<DispatchEvent>>>;
}

struct SchedulerKey;
impl TypeMapKey for SchedulerKey {
    type Value = Arc<RwLock<Scheduler>>;
}

struct Handler;
impl EventHandler for Handler {
    // We want to dispatch an event whenever a new reaction has been added.
    fn reaction_add(&self, context: Context, reaction: Reaction) {
        let dispatcher = {
            let mut context = context.data.write();
            context.get_mut::<DispatcherKey>().expect("Expected Dispatcher.").clone()
        };

        dispatcher.write().dispatch_event(
            &DispatchEvent::ReactEvent(reaction.message_id, reaction.user_id));
    }
}

group!({
    name: "remind_me",
    options: {
        prefixes: ["rm", "reminder"],
    },
    commands: [set_reminder],
});

#[help]
fn my_help(
    context: &mut Context,
    msg: &Message,
    args: Args,
    help_options: &'static HelpOptions,
    groups: &[&'static CommandGroup],
    owners: HashSet<UserId>
) -> CommandResult {
    help_commands::with_embeds(context, msg, args, &help_options, groups, owners)
}

fn main() {
    // Configure the client with your Discord bot token in the environment.
    let token = env::var("DISCORD_TOKEN").expect(
        "Expected a token in the environment",
    );
    let mut client = Client::new(&token, Handler)
        .expect("Err creating client");

    {
        let mut data = client.data.write();
        // We create a new scheduler with 4 internal threads. Why 4? It really
        // is just an arbitrary number, you are often better setting this
        // based on your CPU.
        // When a task is due, a thread from the threadpool will be used to
        // avoid blocking the scheduler thread.
        let scheduler = Scheduler::new(4);
        let scheduler = Arc::new(RwLock::new(scheduler));

        let mut dispatcher: Dispatcher<DispatchEvent> = Dispatcher::default();
        // Once receiving an event to dispatch, the amount of threads
        // set via `num_threads` will dispatch in parallel.
        dispatcher.num_threads(4).expect("Could not construct threadpool");

        data.insert::<DispatcherKey>(Arc::new(RwLock::new(dispatcher)));
        data.insert::<SchedulerKey>(scheduler);
    }

    // We will fetch your bot's id.
    let bot_id = match client.cache_and_http.http.get_current_application_info() {
        Ok(info) => {
            info.id
        },
        Err(why) => panic!("Could not access application info: {:?}", why),
    };

    client.with_framework(
        // Configures the client, allowing for options to mutate how the
        // framework functions.
        StandardFramework::new()
        .configure(|c| c
            .with_whitespace(true)
            .on_mention(Some(bot_id))
            .prefix("~")
            .delimiters(vec![", ", ","]))
        .on_dispatch_error(|ctx, msg, error| {
            if let DispatchError::Ratelimited(seconds) = error {
                let _ = msg.channel_id.say(&ctx.http, &format!("Try this again in {} seconds.", seconds));
            }
        })
        .after(|_ctx, _msg, cmd_name, error| {

        if let Err(why) = error {
            println!("Error in {}: {:?}", cmd_name, why);
        }
    })
        .help(&MY_HELP)
        .group(&REMIND_ME_GROUP)
    );

    if let Err(why) = client.start() {
        println!("Client error: {:?}", why);
    }
}

// Just a helper-function for creating the closure we want to use as listener.
// It saves us from writing the same trigger twice for repeated and non-repeated
// tasks (see remind-me command below).
fn thanks_for_reacting(http: Arc<Http>, channel: ChannelId) ->
    Box<Fn(&DispatchEvent) -> Option<DispatcherRequest> + Send + Sync> {

    Box::new(move |_| {
        if let Err(why) = channel.say(&http, "Thanks for reacting!") {
            println!("Could not send message: {:?}", why);
        }

        Some(DispatcherRequest::StopListening)
    })
}

#[command]
#[aliases("add")]
fn set_reminder(context: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
    // It might be smart to set a moderately high minimum value for `time`
    // to avoid abuse like tasks that repeat every 100ms, especially since
    // channels have send-message rate limits.
    let time: u64 = args.single()?;
    let repeat: bool = args.single()?;
    let args = args.rest().to_string();

    let scheduler = {
        let mut context = context.data.write();
        context.get_mut::<SchedulerKey>().expect("Expected Scheduler.").clone()
    };

    let dispatcher = {
        let mut context = context.data.write();
        context.get_mut::<DispatcherKey>().expect("Expected Dispatcher.").clone()
    };

    let http = context.http.clone();
    let msg = msg.clone();

    let mut scheduler = scheduler.write();

    // First, we check if the user wants a repeated task or not.
    if repeat {
        // Chrono's duration can also be negative
        // and therefore we cast to `i64`.
        scheduler.add_task_duration(Duration::milliseconds(time as i64), move |_| {
            let bot_msg = match msg.channel_id.say(&http, &args) {
                Ok(msg) => msg,
                // We could not send the message, thus we will try sending it
                // again in five seconds.
                // It might be wise to keep a counter for maximum tries.
                // If the channel got deleted, trying to send a message will
                // always fail.
                Err(why) => {
                    println!("Error sending message: {:?}.", why);

                    return DateResult::Repeat(
                        Utc::now() + Duration::milliseconds(5000))
                },
            };

            let http = http.clone();

            // We add a function to dispatch for a certain event.
            dispatcher.write()
                .add_fn(DispatchEvent::ReactEvent(bot_msg.id, msg.author.id),
                    // The `thanks_for_reacting`-function creates a function
                    // to schedule.
                    thanks_for_reacting(http, bot_msg.channel_id));

            // We return that our date shall happen again, therefore we need
            // to tell when this shall be.
            DateResult::Repeat(Utc::now() + Duration::milliseconds(time as i64))
        });
    } else {
        // Pretty much identical with the `true`-case except for the returned
        // variant.
        scheduler.add_task_duration(Duration::milliseconds(time as i64), move |_| {
            let bot_msg = match msg.channel_id.say(&http, &args) {
                Ok(msg) => msg,
                Err(why) => {
                    println!("Error sending message: {:?}.", why);

                    return DateResult::Repeat(
                        Utc::now() + Duration::milliseconds(5000)
                    )
                },
            };
            let http = http.clone();

            dispatcher.write()
                .add_fn(DispatchEvent::ReactEvent(bot_msg.id, msg.author.id),
                    thanks_for_reacting(http, bot_msg.channel_id));

            // The task is done and that's it, we do not to repeat it.
            DateResult::Done
        });
    };

    Ok(())
}
<|endoftext|>


<commit_before>#![allow(dead_code)]
fn main() {
    let (word_a, word_b) = words();
    let message = format!("{}{}！", word_a, word_b);
    output(message);
    //output(message);
}

fn words() -> (String, String) {
    (format!("こんにちは"), format!("世界"))
}

fn output(text: String) {
    let kanji_only = remove_hiragana(text);
    println!("{}", kanji_only);
    /*
    ゴール2：次の行をアンコメントすると何がおきるでしょうか？
    これをコンパイルを通すにはどうすれば良いでしょうか？
    */
    // println("ひらがなを抜き取ると：{:?} → {:?}", text, kanji_only);

    /*
    ゴール3：データをコピーせずにコンパイルを通すにはどおすれば良いでしょうか？
    所有権の移動のみを使って解決してください
    */
}

fn remove_hiragana(text: String) -> String {
    /*
     ゴール1：コンパイルを通すには何を変更すれば良いでしょうか
    */
    let result = String::new();
    for c in text.chars() {
        if c < 'あ' || 'ん' < c {
            result.push(c);
        };
    }
    result
}

<commit_msg>Fix the first hiragana letter.<commit_after>#![allow(dead_code)]
fn main() {
    let (word_a, word_b) = words();
    let message = format!("{}{}！", word_a, word_b);
    output(message);
    //output(message);
}

fn words() -> (String, String) {
    (format!("こんにちは"), format!("世界"))
}

fn output(text: String) {
    let kanji_only = remove_hiragana(text);
    println!("{}", kanji_only);
    /*
    ゴール2：次の行をアンコメントすると何がおきるでしょうか？
    これをコンパイルを通すにはどうすれば良いでしょうか？
    */
    // println("ひらがなを抜き取ると：{:?} → {:?}", text, kanji_only);

    /*
    ゴール3：データをコピーせずにコンパイルを通すにはどおすれば良いでしょうか？
    所有権の移動のみを使って解決してください
    */
}

fn remove_hiragana(text: String) -> String {
    /*
     ゴール1：コンパイルを通すには何を変更すれば良いでしょうか
    */
    let result = String::new();
    for c in text.chars() {
        if c < 'ぁ' || 'ん' < c {
            result.push(c);
        };
    }
    result
}

<|endoftext|>


<commit_before>pub fn count(lines: &[&str]) -> u32 {
    unimplemented!("Determine the count of rectangles in the ASCII diagram represented by the following lines:\n{:#?}\n.", lines);
}
<commit_msg>rectangles: Add newline to the stub template message (#624)<commit_after>pub fn count(lines: &[&str]) -> u32 {
    unimplemented!("\nDetermine the count of rectangles in the ASCII diagram represented by the following lines:\n{:#?}\n.", lines);
}
<|endoftext|>