Support
Quality
Security
License
Reuse
kandi has reviewed crate and discovered the below as its top functions. This is intended to give you an instant insight into crate implemented functionality, and help decide if they suit your requirements.
CrateDB is a distributed SQL database that makes it simple to store and analyze massive amounts of machine data in real-time.
Different behavior between match and unwrap
pub struct OutputStreamHandle {
mixer: Weak<DynamicMixerController<f32>>,
}
let (_, handle) = OutputStream::try_default().unwrap();
if let Ok((_, handle)) = OutputStream::try_default() {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
{
let _var = OutputStream::try_default();
if let Ok((_, handle)) = _var {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
}
let (_stream, handle) = OutputStream::try_default().unwrap();
let _ = m.lock().unwrap();
let _lock = m.lock().unwrap():
let lock = m.lock().unwrap();
...
drop(lock);
-----------------------
pub struct OutputStreamHandle {
mixer: Weak<DynamicMixerController<f32>>,
}
let (_, handle) = OutputStream::try_default().unwrap();
if let Ok((_, handle)) = OutputStream::try_default() {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
{
let _var = OutputStream::try_default();
if let Ok((_, handle)) = _var {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
}
let (_stream, handle) = OutputStream::try_default().unwrap();
let _ = m.lock().unwrap();
let _lock = m.lock().unwrap():
let lock = m.lock().unwrap();
...
drop(lock);
-----------------------
pub struct OutputStreamHandle {
mixer: Weak<DynamicMixerController<f32>>,
}
let (_, handle) = OutputStream::try_default().unwrap();
if let Ok((_, handle)) = OutputStream::try_default() {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
{
let _var = OutputStream::try_default();
if let Ok((_, handle)) = _var {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
}
let (_stream, handle) = OutputStream::try_default().unwrap();
let _ = m.lock().unwrap();
let _lock = m.lock().unwrap():
let lock = m.lock().unwrap();
...
drop(lock);
-----------------------
pub struct OutputStreamHandle {
mixer: Weak<DynamicMixerController<f32>>,
}
let (_, handle) = OutputStream::try_default().unwrap();
if let Ok((_, handle)) = OutputStream::try_default() {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
{
let _var = OutputStream::try_default();
if let Ok((_, handle)) = _var {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
}
let (_stream, handle) = OutputStream::try_default().unwrap();
let _ = m.lock().unwrap();
let _lock = m.lock().unwrap():
let lock = m.lock().unwrap();
...
drop(lock);
-----------------------
pub struct OutputStreamHandle {
mixer: Weak<DynamicMixerController<f32>>,
}
let (_, handle) = OutputStream::try_default().unwrap();
if let Ok((_, handle)) = OutputStream::try_default() {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
{
let _var = OutputStream::try_default();
if let Ok((_, handle)) = _var {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
}
let (_stream, handle) = OutputStream::try_default().unwrap();
let _ = m.lock().unwrap();
let _lock = m.lock().unwrap():
let lock = m.lock().unwrap();
...
drop(lock);
-----------------------
pub struct OutputStreamHandle {
mixer: Weak<DynamicMixerController<f32>>,
}
let (_, handle) = OutputStream::try_default().unwrap();
if let Ok((_, handle)) = OutputStream::try_default() {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
{
let _var = OutputStream::try_default();
if let Ok((_, handle)) = _var {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
}
let (_stream, handle) = OutputStream::try_default().unwrap();
let _ = m.lock().unwrap();
let _lock = m.lock().unwrap():
let lock = m.lock().unwrap();
...
drop(lock);
-----------------------
pub struct OutputStreamHandle {
mixer: Weak<DynamicMixerController<f32>>,
}
let (_, handle) = OutputStream::try_default().unwrap();
if let Ok((_, handle)) = OutputStream::try_default() {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
{
let _var = OutputStream::try_default();
if let Ok((_, handle)) = _var {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
}
let (_stream, handle) = OutputStream::try_default().unwrap();
let _ = m.lock().unwrap();
let _lock = m.lock().unwrap():
let lock = m.lock().unwrap();
...
drop(lock);
-----------------------
pub struct OutputStreamHandle {
mixer: Weak<DynamicMixerController<f32>>,
}
let (_, handle) = OutputStream::try_default().unwrap();
if let Ok((_, handle)) = OutputStream::try_default() {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
{
let _var = OutputStream::try_default();
if let Ok((_, handle)) = _var {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
}
let (_stream, handle) = OutputStream::try_default().unwrap();
let _ = m.lock().unwrap();
let _lock = m.lock().unwrap():
let lock = m.lock().unwrap();
...
drop(lock);
Specialising Range or overloading ".."
use std::ops::{Index, IndexMut, Range, Deref, DerefMut};
#[repr(transparent)] // Because of this we can soundly cast `&{mut }[T]` to `&{mut }MySlice<T>`.
pub struct MySlice<T>([T]);
impl<'a, T> From<&'a [T]> for &'a MySlice<T> {
fn from(v: &'a [T]) -> &'a MySlice<T> {
unsafe { &*(v as *const [T] as *const MySlice<T>) }
}
}
impl<'a, T> From<&'a mut [T]> for &'a mut MySlice<T> {
fn from(v: &'a mut [T]) -> &'a mut MySlice<T> {
unsafe { &mut *(v as *mut [T] as *mut MySlice<T>) }
}
}
impl<T> Index<usize> for MySlice<T> {
type Output = T;
fn index(&self, idx: usize) -> &Self::Output { &self.0[idx] }
}
impl<T> IndexMut<usize> for MySlice<T> {
fn index_mut(&mut self, idx: usize) -> &mut Self::Output { &mut self.0[idx] }
}
impl<T> Index<Range<usize>> for MySlice<T> {
type Output = MySlice<T>;
fn index(&self, idx: Range<usize>) -> &Self::Output { self.0[idx].into() }
}
impl<T> IndexMut<Range<usize>> for MySlice<T> {
fn index_mut(&mut self, idx: Range<usize>) -> &mut Self::Output { (&mut self.0[idx]).into() }
}
// And so on, for all range types...
pub struct MyVec<T>(pub Vec<T>);
impl<T> Deref for MyVec<T> {
type Target = MySlice<T>;
fn deref(&self) -> &Self::Target { self.0.as_slice().into() }
}
impl<T> DerefMut for MyVec<T> {
fn deref_mut(&mut self) -> &mut Self::Target { self.0.as_mut_slice().into() }
}
-----------------------
// A dummy type to illustrate the types I want to work with
// Different TypeInfo will give me different and incompatible
// types that wrap integers, which is what I want.
trait TypeInfo {
type WrappedType: num::PrimInt;
}
// A wrapper wraps the type from the TypeInfo trait;
// the TypeInfo trait specifies the type when I define what
// operations I will allow.
#[derive(Debug, Clone, Copy)]
struct Wrapper<T: TypeInfo>(T::WrappedType);
// Trait that determines which sequences an index can index
trait CanIndex<Seq: ?Sized> {}
// For indexing... (You get too deeply nested genetics without it)
// Maybe I can get rid of it, but that is for another day...
pub trait IndexType {
fn as_index(&self) -> usize;
}
impl<TI> IndexType for Wrapper<TI>
where
TI: TypeInfo<WrappedType = usize>,
{
fn as_index(&self) -> usize {
self.0
}
}
// Generic index implementation. (The real situation is a bit more
// complicated because I need to specify which types each index type
// is allowed to index, but this is the gist of it)
// Indexing a single element in a vector
impl<TI, T> std::ops::Index<Wrapper<TI>> for Vec<T>
where
TI: TypeInfo,
TI: CanIndex<Vec<T>>,
Wrapper<TI>: IndexType,
{
type Output = T;
fn index(&self, i: Wrapper<TI>) -> &Self::Output {
&self[i.as_index()]
}
}
// Indexing a single element in a slice
impl<TI, T> std::ops::Index<Wrapper<TI>> for [T]
where
TI: TypeInfo,
TI: CanIndex<[T]>,
Wrapper<TI>: IndexType,
{
type Output = T;
fn index(&self, i: Wrapper<TI>) -> &Self::Output {
&self[i.as_index()]
}
}
// My own type of ranges, now that I cannot use the built-in type...
/// Wrapper of Range that we can work with within Rust's type system
#[derive(Clone, Copy)]
pub enum Range<Idx> {
Closed(Idx, Idx), // start..end
Left(Idx), // start..
Right(Idx), // ..end
Full, // ..
}
pub trait GenRange<R, Idx> {
fn range(r: R) -> Range<Idx>;
}
/*
Now implement that trait for the different range types.
Is there a better way?
*/
// Now I can build ranges with this function:
pub fn range<Idx, R: GenRange<R, Idx>>(r: R) -> Range<Idx> {
R::range(r)
}
impl<Idx, T> std::ops::Index<Range<Idx>> for Vec<T>
where
Idx: IndexType,
Idx: CanIndex<Vec<T>>,
{
type Output = [T];
fn index(&self, r: Range<Idx>) -> &Self::Output {
match r {
Range::Closed(start, end) => &self[start.as_index()..end.as_index()],
Range::Left(start) => &self[start.as_index()..],
Range::Right(end) => &self[..end.as_index()],
Range::Full => &self[..],
}
}
}
impl<Idx, T> std::ops::Index<Range<Idx>> for [T]
where
Idx: IndexType,
Idx: CanIndex<[T]>,
{
type Output = [T];
fn index(&self, r: Range<Idx>) -> &Self::Output {
match r {
Range::Closed(start, end) => &self[start.as_index()..end.as_index()],
Range::Left(start) => &self[start.as_index()..],
Range::Right(end) => &self[..end.as_index()],
Range::Full => &self[..],
}
}
}
-----------------------
// A dummy type to illustrate the types I want to work with
// Different TypeInfo will give me different and incompatible
// types that wrap integers, which is what I want.
trait TypeInfo {
type WrappedType: num::PrimInt;
}
// A wrapper wraps the type from the TypeInfo trait;
// the TypeInfo trait specifies the type when I define what
// operations I will allow.
#[derive(Debug, Clone, Copy)]
struct Wrapper<T: TypeInfo>(T::WrappedType);
// Trait that determines which sequences an index can index
trait CanIndex<Seq: ?Sized> {}
// For indexing... (You get too deeply nested genetics without it)
// Maybe I can get rid of it, but that is for another day...
pub trait IndexType {
fn as_index(&self) -> usize;
}
impl<TI> IndexType for Wrapper<TI>
where
TI: TypeInfo<WrappedType = usize>,
{
fn as_index(&self) -> usize {
self.0
}
}
// Generic index implementation. (The real situation is a bit more
// complicated because I need to specify which types each index type
// is allowed to index, but this is the gist of it)
// Indexing a single element in a vector
impl<TI, T> std::ops::Index<Wrapper<TI>> for Vec<T>
where
TI: TypeInfo,
TI: CanIndex<Vec<T>>,
Wrapper<TI>: IndexType,
{
type Output = T;
fn index(&self, i: Wrapper<TI>) -> &Self::Output {
&self[i.as_index()]
}
}
// Indexing a single element in a slice
impl<TI, T> std::ops::Index<Wrapper<TI>> for [T]
where
TI: TypeInfo,
TI: CanIndex<[T]>,
Wrapper<TI>: IndexType,
{
type Output = T;
fn index(&self, i: Wrapper<TI>) -> &Self::Output {
&self[i.as_index()]
}
}
// My own type of ranges, now that I cannot use the built-in type...
/// Wrapper of Range that we can work with within Rust's type system
#[derive(Clone, Copy)]
pub enum Range<Idx> {
Closed(Idx, Idx), // start..end
Left(Idx), // start..
Right(Idx), // ..end
Full, // ..
}
pub trait GenRange<R, Idx> {
fn range(r: R) -> Range<Idx>;
}
/*
Now implement that trait for the different range types.
Is there a better way?
*/
// Now I can build ranges with this function:
pub fn range<Idx, R: GenRange<R, Idx>>(r: R) -> Range<Idx> {
R::range(r)
}
impl<Idx, T> std::ops::Index<Range<Idx>> for Vec<T>
where
Idx: IndexType,
Idx: CanIndex<Vec<T>>,
{
type Output = [T];
fn index(&self, r: Range<Idx>) -> &Self::Output {
match r {
Range::Closed(start, end) => &self[start.as_index()..end.as_index()],
Range::Left(start) => &self[start.as_index()..],
Range::Right(end) => &self[..end.as_index()],
Range::Full => &self[..],
}
}
}
impl<Idx, T> std::ops::Index<Range<Idx>> for [T]
where
Idx: IndexType,
Idx: CanIndex<[T]>,
{
type Output = [T];
fn index(&self, r: Range<Idx>) -> &Self::Output {
match r {
Range::Closed(start, end) => &self[start.as_index()..end.as_index()],
Range::Left(start) => &self[start.as_index()..],
Range::Right(end) => &self[..end.as_index()],
Range::Full => &self[..],
}
}
}
-----------------------
// A dummy type to illustrate the types I want to work with
// Different TypeInfo will give me different and incompatible
// types that wrap integers, which is what I want.
trait TypeInfo {
type WrappedType: num::PrimInt;
}
// A wrapper wraps the type from the TypeInfo trait;
// the TypeInfo trait specifies the type when I define what
// operations I will allow.
#[derive(Debug, Clone, Copy)]
struct Wrapper<T: TypeInfo>(T::WrappedType);
// Trait that determines which sequences an index can index
trait CanIndex<Seq: ?Sized> {}
// For indexing... (You get too deeply nested genetics without it)
// Maybe I can get rid of it, but that is for another day...
pub trait IndexType {
fn as_index(&self) -> usize;
}
impl<TI> IndexType for Wrapper<TI>
where
TI: TypeInfo<WrappedType = usize>,
{
fn as_index(&self) -> usize {
self.0
}
}
// Generic index implementation. (The real situation is a bit more
// complicated because I need to specify which types each index type
// is allowed to index, but this is the gist of it)
// Indexing a single element in a vector
impl<TI, T> std::ops::Index<Wrapper<TI>> for Vec<T>
where
TI: TypeInfo,
TI: CanIndex<Vec<T>>,
Wrapper<TI>: IndexType,
{
type Output = T;
fn index(&self, i: Wrapper<TI>) -> &Self::Output {
&self[i.as_index()]
}
}
// Indexing a single element in a slice
impl<TI, T> std::ops::Index<Wrapper<TI>> for [T]
where
TI: TypeInfo,
TI: CanIndex<[T]>,
Wrapper<TI>: IndexType,
{
type Output = T;
fn index(&self, i: Wrapper<TI>) -> &Self::Output {
&self[i.as_index()]
}
}
// My own type of ranges, now that I cannot use the built-in type...
/// Wrapper of Range that we can work with within Rust's type system
#[derive(Clone, Copy)]
pub enum Range<Idx> {
Closed(Idx, Idx), // start..end
Left(Idx), // start..
Right(Idx), // ..end
Full, // ..
}
pub trait GenRange<R, Idx> {
fn range(r: R) -> Range<Idx>;
}
/*
Now implement that trait for the different range types.
Is there a better way?
*/
// Now I can build ranges with this function:
pub fn range<Idx, R: GenRange<R, Idx>>(r: R) -> Range<Idx> {
R::range(r)
}
impl<Idx, T> std::ops::Index<Range<Idx>> for Vec<T>
where
Idx: IndexType,
Idx: CanIndex<Vec<T>>,
{
type Output = [T];
fn index(&self, r: Range<Idx>) -> &Self::Output {
match r {
Range::Closed(start, end) => &self[start.as_index()..end.as_index()],
Range::Left(start) => &self[start.as_index()..],
Range::Right(end) => &self[..end.as_index()],
Range::Full => &self[..],
}
}
}
impl<Idx, T> std::ops::Index<Range<Idx>> for [T]
where
Idx: IndexType,
Idx: CanIndex<[T]>,
{
type Output = [T];
fn index(&self, r: Range<Idx>) -> &Self::Output {
match r {
Range::Closed(start, end) => &self[start.as_index()..end.as_index()],
Range::Left(start) => &self[start.as_index()..],
Range::Right(end) => &self[..end.as_index()],
Range::Full => &self[..],
}
}
}
-----------------------
// A dummy type to illustrate the types I want to work with
// Different TypeInfo will give me different and incompatible
// types that wrap integers, which is what I want.
trait TypeInfo {
type WrappedType: num::PrimInt;
}
// A wrapper wraps the type from the TypeInfo trait;
// the TypeInfo trait specifies the type when I define what
// operations I will allow.
#[derive(Debug, Clone, Copy)]
struct Wrapper<T: TypeInfo>(T::WrappedType);
// Trait that determines which sequences an index can index
trait CanIndex<Seq: ?Sized> {}
// For indexing... (You get too deeply nested genetics without it)
// Maybe I can get rid of it, but that is for another day...
pub trait IndexType {
fn as_index(&self) -> usize;
}
impl<TI> IndexType for Wrapper<TI>
where
TI: TypeInfo<WrappedType = usize>,
{
fn as_index(&self) -> usize {
self.0
}
}
// Generic index implementation. (The real situation is a bit more
// complicated because I need to specify which types each index type
// is allowed to index, but this is the gist of it)
// Indexing a single element in a vector
impl<TI, T> std::ops::Index<Wrapper<TI>> for Vec<T>
where
TI: TypeInfo,
TI: CanIndex<Vec<T>>,
Wrapper<TI>: IndexType,
{
type Output = T;
fn index(&self, i: Wrapper<TI>) -> &Self::Output {
&self[i.as_index()]
}
}
// Indexing a single element in a slice
impl<TI, T> std::ops::Index<Wrapper<TI>> for [T]
where
TI: TypeInfo,
TI: CanIndex<[T]>,
Wrapper<TI>: IndexType,
{
type Output = T;
fn index(&self, i: Wrapper<TI>) -> &Self::Output {
&self[i.as_index()]
}
}
// My own type of ranges, now that I cannot use the built-in type...
/// Wrapper of Range that we can work with within Rust's type system
#[derive(Clone, Copy)]
pub enum Range<Idx> {
Closed(Idx, Idx), // start..end
Left(Idx), // start..
Right(Idx), // ..end
Full, // ..
}
pub trait GenRange<R, Idx> {
fn range(r: R) -> Range<Idx>;
}
/*
Now implement that trait for the different range types.
Is there a better way?
*/
// Now I can build ranges with this function:
pub fn range<Idx, R: GenRange<R, Idx>>(r: R) -> Range<Idx> {
R::range(r)
}
impl<Idx, T> std::ops::Index<Range<Idx>> for Vec<T>
where
Idx: IndexType,
Idx: CanIndex<Vec<T>>,
{
type Output = [T];
fn index(&self, r: Range<Idx>) -> &Self::Output {
match r {
Range::Closed(start, end) => &self[start.as_index()..end.as_index()],
Range::Left(start) => &self[start.as_index()..],
Range::Right(end) => &self[..end.as_index()],
Range::Full => &self[..],
}
}
}
impl<Idx, T> std::ops::Index<Range<Idx>> for [T]
where
Idx: IndexType,
Idx: CanIndex<[T]>,
{
type Output = [T];
fn index(&self, r: Range<Idx>) -> &Self::Output {
match r {
Range::Closed(start, end) => &self[start.as_index()..end.as_index()],
Range::Left(start) => &self[start.as_index()..],
Range::Right(end) => &self[..end.as_index()],
Range::Full => &self[..],
}
}
}
-----------------------
// A dummy type to illustrate the types I want to work with
// Different TypeInfo will give me different and incompatible
// types that wrap integers, which is what I want.
trait TypeInfo {
type WrappedType: num::PrimInt;
}
// A wrapper wraps the type from the TypeInfo trait;
// the TypeInfo trait specifies the type when I define what
// operations I will allow.
#[derive(Debug, Clone, Copy)]
struct Wrapper<T: TypeInfo>(T::WrappedType);
// Trait that determines which sequences an index can index
trait CanIndex<Seq: ?Sized> {}
// For indexing... (You get too deeply nested genetics without it)
// Maybe I can get rid of it, but that is for another day...
pub trait IndexType {
fn as_index(&self) -> usize;
}
impl<TI> IndexType for Wrapper<TI>
where
TI: TypeInfo<WrappedType = usize>,
{
fn as_index(&self) -> usize {
self.0
}
}
// Generic index implementation. (The real situation is a bit more
// complicated because I need to specify which types each index type
// is allowed to index, but this is the gist of it)
// Indexing a single element in a vector
impl<TI, T> std::ops::Index<Wrapper<TI>> for Vec<T>
where
TI: TypeInfo,
TI: CanIndex<Vec<T>>,
Wrapper<TI>: IndexType,
{
type Output = T;
fn index(&self, i: Wrapper<TI>) -> &Self::Output {
&self[i.as_index()]
}
}
// Indexing a single element in a slice
impl<TI, T> std::ops::Index<Wrapper<TI>> for [T]
where
TI: TypeInfo,
TI: CanIndex<[T]>,
Wrapper<TI>: IndexType,
{
type Output = T;
fn index(&self, i: Wrapper<TI>) -> &Self::Output {
&self[i.as_index()]
}
}
// My own type of ranges, now that I cannot use the built-in type...
/// Wrapper of Range that we can work with within Rust's type system
#[derive(Clone, Copy)]
pub enum Range<Idx> {
Closed(Idx, Idx), // start..end
Left(Idx), // start..
Right(Idx), // ..end
Full, // ..
}
pub trait GenRange<R, Idx> {
fn range(r: R) -> Range<Idx>;
}
/*
Now implement that trait for the different range types.
Is there a better way?
*/
// Now I can build ranges with this function:
pub fn range<Idx, R: GenRange<R, Idx>>(r: R) -> Range<Idx> {
R::range(r)
}
impl<Idx, T> std::ops::Index<Range<Idx>> for Vec<T>
where
Idx: IndexType,
Idx: CanIndex<Vec<T>>,
{
type Output = [T];
fn index(&self, r: Range<Idx>) -> &Self::Output {
match r {
Range::Closed(start, end) => &self[start.as_index()..end.as_index()],
Range::Left(start) => &self[start.as_index()..],
Range::Right(end) => &self[..end.as_index()],
Range::Full => &self[..],
}
}
}
impl<Idx, T> std::ops::Index<Range<Idx>> for [T]
where
Idx: IndexType,
Idx: CanIndex<[T]>,
{
type Output = [T];
fn index(&self, r: Range<Idx>) -> &Self::Output {
match r {
Range::Closed(start, end) => &self[start.as_index()..end.as_index()],
Range::Left(start) => &self[start.as_index()..],
Range::Right(end) => &self[..end.as_index()],
Range::Full => &self[..],
}
}
}
-----------------------
// A dummy type to illustrate the types I want to work with
// Different TypeInfo will give me different and incompatible
// types that wrap integers, which is what I want.
trait TypeInfo {
type WrappedType: num::PrimInt;
}
// A wrapper wraps the type from the TypeInfo trait;
// the TypeInfo trait specifies the type when I define what
// operations I will allow.
#[derive(Debug, Clone, Copy)]
struct Wrapper<T: TypeInfo>(T::WrappedType);
// Trait that determines which sequences an index can index
trait CanIndex<Seq: ?Sized> {}
// For indexing... (You get too deeply nested genetics without it)
// Maybe I can get rid of it, but that is for another day...
pub trait IndexType {
fn as_index(&self) -> usize;
}
impl<TI> IndexType for Wrapper<TI>
where
TI: TypeInfo<WrappedType = usize>,
{
fn as_index(&self) -> usize {
self.0
}
}
// Generic index implementation. (The real situation is a bit more
// complicated because I need to specify which types each index type
// is allowed to index, but this is the gist of it)
// Indexing a single element in a vector
impl<TI, T> std::ops::Index<Wrapper<TI>> for Vec<T>
where
TI: TypeInfo,
TI: CanIndex<Vec<T>>,
Wrapper<TI>: IndexType,
{
type Output = T;
fn index(&self, i: Wrapper<TI>) -> &Self::Output {
&self[i.as_index()]
}
}
// Indexing a single element in a slice
impl<TI, T> std::ops::Index<Wrapper<TI>> for [T]
where
TI: TypeInfo,
TI: CanIndex<[T]>,
Wrapper<TI>: IndexType,
{
type Output = T;
fn index(&self, i: Wrapper<TI>) -> &Self::Output {
&self[i.as_index()]
}
}
// My own type of ranges, now that I cannot use the built-in type...
/// Wrapper of Range that we can work with within Rust's type system
#[derive(Clone, Copy)]
pub enum Range<Idx> {
Closed(Idx, Idx), // start..end
Left(Idx), // start..
Right(Idx), // ..end
Full, // ..
}
pub trait GenRange<R, Idx> {
fn range(r: R) -> Range<Idx>;
}
/*
Now implement that trait for the different range types.
Is there a better way?
*/
// Now I can build ranges with this function:
pub fn range<Idx, R: GenRange<R, Idx>>(r: R) -> Range<Idx> {
R::range(r)
}
impl<Idx, T> std::ops::Index<Range<Idx>> for Vec<T>
where
Idx: IndexType,
Idx: CanIndex<Vec<T>>,
{
type Output = [T];
fn index(&self, r: Range<Idx>) -> &Self::Output {
match r {
Range::Closed(start, end) => &self[start.as_index()..end.as_index()],
Range::Left(start) => &self[start.as_index()..],
Range::Right(end) => &self[..end.as_index()],
Range::Full => &self[..],
}
}
}
impl<Idx, T> std::ops::Index<Range<Idx>> for [T]
where
Idx: IndexType,
Idx: CanIndex<[T]>,
{
type Output = [T];
fn index(&self, r: Range<Idx>) -> &Self::Output {
match r {
Range::Closed(start, end) => &self[start.as_index()..end.as_index()],
Range::Left(start) => &self[start.as_index()..],
Range::Right(end) => &self[..end.as_index()],
Range::Full => &self[..],
}
}
}
-----------------------
// A dummy type to illustrate the types I want to work with
// Different TypeInfo will give me different and incompatible
// types that wrap integers, which is what I want.
trait TypeInfo {
type WrappedType: num::PrimInt;
}
// A wrapper wraps the type from the TypeInfo trait;
// the TypeInfo trait specifies the type when I define what
// operations I will allow.
#[derive(Debug, Clone, Copy)]
struct Wrapper<T: TypeInfo>(T::WrappedType);
// Trait that determines which sequences an index can index
trait CanIndex<Seq: ?Sized> {}
// For indexing... (You get too deeply nested genetics without it)
// Maybe I can get rid of it, but that is for another day...
pub trait IndexType {
fn as_index(&self) -> usize;
}
impl<TI> IndexType for Wrapper<TI>
where
TI: TypeInfo<WrappedType = usize>,
{
fn as_index(&self) -> usize {
self.0
}
}
// Generic index implementation. (The real situation is a bit more
// complicated because I need to specify which types each index type
// is allowed to index, but this is the gist of it)
// Indexing a single element in a vector
impl<TI, T> std::ops::Index<Wrapper<TI>> for Vec<T>
where
TI: TypeInfo,
TI: CanIndex<Vec<T>>,
Wrapper<TI>: IndexType,
{
type Output = T;
fn index(&self, i: Wrapper<TI>) -> &Self::Output {
&self[i.as_index()]
}
}
// Indexing a single element in a slice
impl<TI, T> std::ops::Index<Wrapper<TI>> for [T]
where
TI: TypeInfo,
TI: CanIndex<[T]>,
Wrapper<TI>: IndexType,
{
type Output = T;
fn index(&self, i: Wrapper<TI>) -> &Self::Output {
&self[i.as_index()]
}
}
// My own type of ranges, now that I cannot use the built-in type...
/// Wrapper of Range that we can work with within Rust's type system
#[derive(Clone, Copy)]
pub enum Range<Idx> {
Closed(Idx, Idx), // start..end
Left(Idx), // start..
Right(Idx), // ..end
Full, // ..
}
pub trait GenRange<R, Idx> {
fn range(r: R) -> Range<Idx>;
}
/*
Now implement that trait for the different range types.
Is there a better way?
*/
// Now I can build ranges with this function:
pub fn range<Idx, R: GenRange<R, Idx>>(r: R) -> Range<Idx> {
R::range(r)
}
impl<Idx, T> std::ops::Index<Range<Idx>> for Vec<T>
where
Idx: IndexType,
Idx: CanIndex<Vec<T>>,
{
type Output = [T];
fn index(&self, r: Range<Idx>) -> &Self::Output {
match r {
Range::Closed(start, end) => &self[start.as_index()..end.as_index()],
Range::Left(start) => &self[start.as_index()..],
Range::Right(end) => &self[..end.as_index()],
Range::Full => &self[..],
}
}
}
impl<Idx, T> std::ops::Index<Range<Idx>> for [T]
where
Idx: IndexType,
Idx: CanIndex<[T]>,
{
type Output = [T];
fn index(&self, r: Range<Idx>) -> &Self::Output {
match r {
Range::Closed(start, end) => &self[start.as_index()..end.as_index()],
Range::Left(start) => &self[start.as_index()..],
Range::Right(end) => &self[..end.as_index()],
Range::Full => &self[..],
}
}
}
How to import a function in main.rs
crate::another_func_in_main();
use crate::another_func_in_main;
// Then in code, no need for a prefix:
another_func_in_main();
-----------------------
crate::another_func_in_main();
use crate::another_func_in_main;
// Then in code, no need for a prefix:
another_func_in_main();
How to return JSON as a response in Rust Rocket with auto field deserialising?
use rocket::serde::json::Json;
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
pub struct Printers {
pub printers: Vec<Printer>,
}
#[derive(Serialize, Deserialize)]
pub struct Printer {
pub device_type: String,
pub uid: String,
pub provider: String,
pub name: String,
pub connection: String,
pub version: u8,
pub manufacturer: String,
}
#[get("/printers")]
fn printers() -> Json<Printers> {
todo!();
}
-----------------------
[dependencies]
## SEE HERE!!
rocket = {version ="0.5.0-rc.1", features=["json"]}
# other properties omitted for brevity
# You can remove this!! Rocket Contrib doesn't exist in Rocket V0.5
#[dependencies.rocket_contrib]
#version = "0.4.10"
#default-features = false
#features = ["json"]
-----------------------
[package]
#...
[dependencies.rocket]
version = "0.5.0-rc.1"
features = ["json"]
[dependencies.serde]
version = "1.0.136"
features = ["derive"]
[dependencies]
#...
# rocket_contrib not required anymore
// rocket v0.5.0-rc.1
use rocket::{
self,
serde::{json::Json, Deserialize, Serialize},
};
#[derive(Deserialize, Serialize)]
struct User {
name: String,
age: u8,
}
#[rocket::post("/post", format = "json", data = "<user>")]
fn post_data(user: Json<User>) -> Json<User> {
let name: String = user.name.clone();
let age: u8 = user.age.clone();
Json(User { name, age })
}
#[rocket::main]
async fn main() {
if let Err(err) = rocket::build()
.mount("/", rocket::routes![post_data])
.launch()
.await
{
println!("Rocket Rust couldn't take off successfully!");
drop(err); // Drop initiates Rocket-formatted panic
}
}
curl -d '{"age": 12,"name":"John Doe"}' -H 'Content-Type: application/json'
http://localhost:8000/post
# Response
# {"name":"John Doe","age":12}
-----------------------
[package]
#...
[dependencies.rocket]
version = "0.5.0-rc.1"
features = ["json"]
[dependencies.serde]
version = "1.0.136"
features = ["derive"]
[dependencies]
#...
# rocket_contrib not required anymore
// rocket v0.5.0-rc.1
use rocket::{
self,
serde::{json::Json, Deserialize, Serialize},
};
#[derive(Deserialize, Serialize)]
struct User {
name: String,
age: u8,
}
#[rocket::post("/post", format = "json", data = "<user>")]
fn post_data(user: Json<User>) -> Json<User> {
let name: String = user.name.clone();
let age: u8 = user.age.clone();
Json(User { name, age })
}
#[rocket::main]
async fn main() {
if let Err(err) = rocket::build()
.mount("/", rocket::routes![post_data])
.launch()
.await
{
println!("Rocket Rust couldn't take off successfully!");
drop(err); // Drop initiates Rocket-formatted panic
}
}
curl -d '{"age": 12,"name":"John Doe"}' -H 'Content-Type: application/json'
http://localhost:8000/post
# Response
# {"name":"John Doe","age":12}
-----------------------
[package]
#...
[dependencies.rocket]
version = "0.5.0-rc.1"
features = ["json"]
[dependencies.serde]
version = "1.0.136"
features = ["derive"]
[dependencies]
#...
# rocket_contrib not required anymore
// rocket v0.5.0-rc.1
use rocket::{
self,
serde::{json::Json, Deserialize, Serialize},
};
#[derive(Deserialize, Serialize)]
struct User {
name: String,
age: u8,
}
#[rocket::post("/post", format = "json", data = "<user>")]
fn post_data(user: Json<User>) -> Json<User> {
let name: String = user.name.clone();
let age: u8 = user.age.clone();
Json(User { name, age })
}
#[rocket::main]
async fn main() {
if let Err(err) = rocket::build()
.mount("/", rocket::routes![post_data])
.launch()
.await
{
println!("Rocket Rust couldn't take off successfully!");
drop(err); // Drop initiates Rocket-formatted panic
}
}
curl -d '{"age": 12,"name":"John Doe"}' -H 'Content-Type: application/json'
http://localhost:8000/post
# Response
# {"name":"John Doe","age":12}
How to get UniquePtr<EnumMember> on the Rust side? (CXX crate)
impl UniquePtr<SizeType> {}
WASM from Rust not returning the expected types
#[no_mangle]
pub extern "C" fn say(output: &mut (*const u8, i32)) {
let pointcut = "Hello World";
output.1 = 11;
output.0 = pointcut.as_ptr();
}
Struct padding rules in Rust
struct ACG1 {
upper: u32,
time1: u16,
time2: u16,
lower: u16,
}
-----------------------
cargo clean
cargo rustc -- -Zprint-type-sizes
...
print-type-size type: `ACG1`: 12 bytes, alignment: 4 bytes
print-type-size field `.upper`: 4 bytes
print-type-size field `.time1`: 2 bytes
print-type-size field `.time2`: 2 bytes
print-type-size field `.lower`: 2 bytes
print-type-size end padding: 2 bytes
print-type-size type: `ACG2`: 12 bytes, alignment: 4 bytes
print-type-size field `.time1`: 2 bytes
print-type-size field `.time2`: 2 bytes
print-type-size field `.upper`: 4 bytes
print-type-size field `.lower`: 2 bytes
print-type-size end padding: 2 bytes
-----------------------
cargo clean
cargo rustc -- -Zprint-type-sizes
...
print-type-size type: `ACG1`: 12 bytes, alignment: 4 bytes
print-type-size field `.upper`: 4 bytes
print-type-size field `.time1`: 2 bytes
print-type-size field `.time2`: 2 bytes
print-type-size field `.lower`: 2 bytes
print-type-size end padding: 2 bytes
print-type-size type: `ACG2`: 12 bytes, alignment: 4 bytes
print-type-size field `.time1`: 2 bytes
print-type-size field `.time2`: 2 bytes
print-type-size field `.upper`: 4 bytes
print-type-size field `.lower`: 2 bytes
print-type-size end padding: 2 bytes
What is "<[_]>" in Rust?
pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> {
// ...
}
Should I take `self` by value or mutable reference when using the Builder pattern?
pub struct Builder {
name: Option<String>,
stack_size: Option<usize>,
}
pub struct Command {
program: CString,
args: Vec<CString>,
env: CommandEnv,
stdin: Option<Stdio>,
stdout: Option<Stdio>,
stderr: Option<Stdio>,
// ...
}
pub struct OpenOptions {
read: bool,
write: bool,
append: bool,
truncate: bool,
create: bool,
create_new: bool,
// ...
}
-----------------------
pub struct Builder {
name: Option<String>,
stack_size: Option<usize>,
}
pub struct Command {
program: CString,
args: Vec<CString>,
env: CommandEnv,
stdin: Option<Stdio>,
stdout: Option<Stdio>,
stderr: Option<Stdio>,
// ...
}
pub struct OpenOptions {
read: bool,
write: bool,
append: bool,
truncate: bool,
create: bool,
create_new: bool,
// ...
}
-----------------------
pub struct Builder {
name: Option<String>,
stack_size: Option<usize>,
}
pub struct Command {
program: CString,
args: Vec<CString>,
env: CommandEnv,
stdin: Option<Stdio>,
stdout: Option<Stdio>,
stderr: Option<Stdio>,
// ...
}
pub struct OpenOptions {
read: bool,
write: bool,
append: bool,
truncate: bool,
create: bool,
create_new: bool,
// ...
}
How do I statically link a Haskell library with a Rust project?
ghc -c -staticlib Lib.hs cwrapper.c -o libtesths.a
extern "C" {
pub fn addTwo(x: i32) -> i32;
pub fn init();
pub fn fin();
}
fn main() {
unsafe {
init();
println!("{}", addTwo(40));
fin();
}
}
% cargo run -q
42
-----------------------
ghc -c -staticlib Lib.hs cwrapper.c -o libtesths.a
extern "C" {
pub fn addTwo(x: i32) -> i32;
pub fn init();
pub fn fin();
}
fn main() {
unsafe {
init();
println!("{}", addTwo(40));
fin();
}
}
% cargo run -q
42
-----------------------
ghc -c -staticlib Lib.hs cwrapper.c -o libtesths.a
extern "C" {
pub fn addTwo(x: i32) -> i32;
pub fn init();
pub fn fin();
}
fn main() {
unsafe {
init();
println!("{}", addTwo(40));
fin();
}
}
% cargo run -q
42
QUESTION
Different behavior between match and unwrap
Asked 2022-Mar-15 at 18:39I have done a small program, and it shows a weird behavior that I cannot explain. I am using rodio crate to try out some audio stuff.
I have done two programs that, in my opinion, should give the same result.
The first one I use matches to handle errors:
let sink : Option<Sink> = match rodio::OutputStream::try_default() {
Ok((_, handle)) => {
match Sink::try_new(&handle) {
Ok(s) => Some(s),
Err(_e) => None,
}
},
Err(_e) => None,
};
println!("{}", sink.unwrap().len());
In the last one, I have used unwrap instead.
let (_, handle) = rodio::OutputStream::try_default().unwrap();
let s = Sink::try_new(&handle).unwrap();
println!("{}",s.len());
The first one executes the print statement as expected, while the last one panics in the second unwrap.
It is very strange to me as soon as there is no error propagation, implicit conversions or other things that can explain that. The problem here is not related to the error itself but the difference between the two codes.
ANSWER
Answered 2021-Sep-30 at 19:08The issue is one of scoping and an implementation detail of rodio: the one critical item here is OutputStream::try_default()
, it doesn't really matter how you handle Sink::try_new(&handle)
it'll always behave the same, not so try_default
, if you match or if let
it it'll work fine, if you unwrap
it it'll fail.
But why would that be, the two should be equivalent. The answer is in the details of rodio, specifically of OutputStreamHandle
:
pub struct OutputStreamHandle {
mixer: Weak<DynamicMixerController<f32>>,
}
So an OutputStreamHandle
(OSH thereafter) only holds a weakref to a DynamicMixerController
, to which the OutputStream
(OS thereafter) holds a strong reference.
This means the OSH only "works" as long as the OS is alive.
let (_, handle) = OutputStream::try_default().unwrap();
does not name the OS, so doesn't hold onto it, it's immediately dropped, the Arc
is released and the OSH holds onto nothing, and the sink is unhappy.
How can the other one work then? Because
if let Ok((_, handle)) = OutputStream::try_default() {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
is really rather
{
let _var = OutputStream::try_default();
if let Ok((_, handle)) = _var {
let sink = Sink::try_new(&handle).unwrap();
println!("match {}", sink.len());
}
}
so the match
/if let
itself is keeping the Result
alive, which is a blessing here (but causes issues just the next question over).
Since the Result
is kept alive, the tuple is kept alive, the OutputStream
is kept alive, the Arc
is kept alive, and thus the OSH has a working mixer
, which the sink can make use of.
You can fix the issue of the second version by binding the OutputStream
to a "proper" name e.g.
let (_stream, handle) = OutputStream::try_default().unwrap();
prefixing a name with _
will create the binding for real, but will suppress the "unused variable" warning.
FWIW being careful around this sort of things is incredibly important around RAII types whose values you "don't need", most commonly mutexes protecting code as opposed to data:
let _ = m.lock().unwrap();
doesn't do anything, the mutex guard is not kept alive, so the lock is immediately released. In that case, you'd rather
let _lock = m.lock().unwrap():
or even better
let lock = m.lock().unwrap();
...
drop(lock);
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
No vulnerabilities reported
Save this library and start creating your kit
Save this library and start creating your kit