Rustc whining about trait scope when it's in scope

Hmm... I looked at the example at Cursor in std::io - Rust but using vec![0; 24], it still complains about it not being &mut [u8] despite the example showing Cursor::new(vec![0; 15]) which should be an error, given what I'm trying to do.

Can you paste your full code? There's a impl Write for Cursor<Vec<u8>> that should work.

vector3:

use byteorder::{ByteOrder,ReadBytesExt,WriteBytesExt};
use pod::Pod;
use std::cmp::{Ordering,PartialEq,PartialOrd};
use std::f32;
use std::fmt;
use std::hash::{Hash,Hasher};
use std::io::{Cursor,Read,Result,Write};
use std::ops::{Add,AddAssign,Div,DivAssign,Index,IndexMut,Mul,MulAssign,Neg,Rem,RemAssign,Sub,SubAssign};

use quaternion::Quaternion;

#[derive(Debug, Default, Copy, Clone)]
pub struct Vector3
{
	pub x: f32,
	pub y: f32,
	pub z: f32,
}

impl Vector3
{
	pub fn abs(&self) -> Vector3
	{
		Vector3
		{
			x: self.x.abs(),
			y: self.y.abs(),
			z: self.z.abs()
		}
	}
	
	pub fn back() -> Vector3
	{
		Vector3 { z: -1f32, ..Default::default() }
	}
	
	pub fn clamp(&self, min: Vector3, max: Vector3) -> Vector3
	{
		let mut x = self.x;
		x = if x > max.x { max.x } else { x };
		x = if x < min.x { min.x } else { x };
		
		let mut y = self.y;
		y = if y > max.y { max.y } else { y };
		y = if y < min.y { min.y } else { y };
		
		let mut z = self.z;
		z = if z > max.z { max.z } else { z };
		z = if z < min.z { min.z } else { z };
		
		Vector3 { x: x, y: y, z: z }
	}
	
	pub fn clamp_mag(&self, max: f32) -> Vector3
	{
		if self.mag_sq() > max * max
		{
			return self.normalized() * max;
		}
		*self
	}
	
	pub fn cross(&self, v: Vector3) -> Vector3
	{
		Vector3
		{
			x: self.y * v.z - self.z * v.y,
			y: self.z * v.x - self.x * v.z,
			z: self.x * v.y - self.y * v.x
		}
	}
	
	pub fn degrees(&self) -> Vector3
	{
		*self * (180f32 / f32::consts::PI)
	}
	
	pub fn dist(&self, v: Vector3) -> f32
	{
		(*self - v).mag()
	}
	
	pub fn dist_sq(&self, v: Vector3) -> f32
	{
		(*self - v).mag_sq()
	}
	
	pub fn dot(&self, v: Vector3) -> f32
	{
		self.x * v.x + self.y * v.y + self.z * v.z
	}
	
	pub fn down() -> Vector3
	{
		Vector3 { y: -1f32, ..Default::default() }
	}
	
	pub fn exclude(&self, ex: Vector3) -> Vector3
	{
		ex - self.project(ex)
	}
	
	pub fn fwd() -> Vector3
	{
		Vector3 { z: 1f32, ..Default::default() }
	}
	
	pub fn left() -> Vector3
	{
		Vector3 { x: -1f32, ..Default::default() }
	}
	
	pub fn mag(&self) -> f32
	{
		self.mag_sq().sqrt()
	}
	
	pub fn mag_sq(&self) -> f32
	{
		self.dot(*self)
	}
	
	pub fn lerp(&self, v: Vector3, amount: f32) -> Vector3
	{
		(*self * (1f32 - amount)) + v * amount
	}
	
	pub fn max(&self, v: Vector3) -> Vector3
	{
		Vector3
		{
			x: if self.x > v.x { self.x } else { v.x },
			y: if self.y > v.y { self.y } else { v.y },
			z: if self.z > v.z { self.z } else { v.z }
		}
	}
	
	pub fn min(&self, v: Vector3) -> Vector3
	{
		Vector3
		{
			x: if self.x < v.x { self.x } else { v.x },
			y: if self.y < v.y { self.y } else { v.y },
			z: if self.z < v.z { self.z } else { v.z }
		}
	}
	
	pub fn move_towards(&self, target: Vector3, max_dist_delta: f32) -> Vector3
	{
		let dist = target - *self;
		let magn = dist.mag();
		if magn <= max_dist_delta || magn == 0f32 { return target; }
		*self + dist / magn * max_dist_delta
	}
	
	pub fn normalized(&self) -> Vector3
	{
		*self / self.mag()
	}
	
	pub fn one() -> Vector3
	{
		Vector3 { x: 1f32, y: 1f32, z: 1f32 }
	}
	
	pub fn project(&self, n: Vector3) -> Vector3
	{
		let dot = n.mag_sq();
		if dot < f32::EPSILON { return Vector3::zero(); }
		n * self.dot(n) / dot
	}
	
	pub fn project_on_plane(&self, pn: Vector3) -> Vector3
	{
		*self - self.project(pn)
	}
	
	pub fn radians(&self) -> Vector3
	{
		*self * (f32::consts::PI / 180f32)
	}
	
	pub fn reflect(&self, n: Vector3) -> Vector3
	{
		*self - (n * self.dot(n) * 2f32)
	}
	
	pub fn right() -> Vector3
	{
		Vector3 { x: 1f32, ..Default::default() }
	}
	
	pub fn rotation(&self, dest: Vector3, up: Vector3) -> Vector3
	{
		let dot = self.dot(dest);
		if (dot+1f32).abs() < 0.000001f32
		{
			return Quaternion::from_vector_scalar(up, f32::consts::PI).eul2();
		}
		if (dot-1f32).abs() < 0.000001f32
		{
			return Quaternion::identity().eul2();
		}
		Quaternion::from_axis_angle(self.cross(dest).normalized(), dot.acos()).eul2()
	}
	
	pub fn sqrt(&self) -> Vector3
	{
		Vector3
		{
			x: self.x.sqrt(),
			y: self.y.sqrt(),
			z: self.z.sqrt()
		}
	}
	
	pub fn transform(&self, r: Quaternion) -> Vector3
	{
		let rx = r.x + r.x;
		let ry = r.y + r.y;
		let rz = r.z + r.z;
		let rwx = r.w * rx;
		let rwy = r.w * ry;
		let rwz = r.w * rz;
		let rxx = r.x * rx;
		let rxy = r.x * ry;
		let rxz = r.x * rz;
		let ryy = r.y * ry;
		let ryz = r.y * rz;
		let rzz = r.z * rz;
		
		Vector3
		{
			x: self.x*(1f32 - ryy - rzz) + self.y*(rxy - rwz) + self.z*(rxz + rwy),
			y: self.x*(rxy + rwz) + self.y*(1f32 - rxx - rzz) + self.z*(ryz - rwx),
			z: self.x*(rxz - rwy) + self.y*(ryz + rwx) + self.z*(1f32 - rxx - ryy)
		}
	}
	
	pub fn up() -> Vector3
	{
		Vector3 { y: 1f32, ..Default::default() }
	}
	
	pub fn zero() -> Vector3
	{
		Vector3 { ..Default::default() }
	}
}

pub trait ReadVector3: ReadBytesExt
{
  #[inline]
  fn read_v3<T: ByteOrder>(&mut self) -> Result<Vector3>
  {
    let mut buf = [0; 12];
    self.read_exact(&mut buf)?;
    Ok(Vector3
    {
      x: T::read_f32(&buf),
      y: T::read_f32(&buf),
      z: T::read_f32(&buf),
    })
  }
}

impl <T: Read + ?Sized> ReadVector3 for T {}

pub trait WriteVector3: WriteBytesExt
{
  #[inline]
  fn write_v3<T: ByteOrder>(&mut self, n: Vector3) -> Result<()>
  {
    let mut buf = [0; 12];
    T::write_f32(&mut buf, n.x);
    T::write_f32(&mut buf, n.y);
    T::write_f32(&mut buf, n.z);
    self.write_all(&buf)
  }
}

impl <T: Write + ?Sized> WriteVector3 for T {}

impl fmt::Display for Vector3
{
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
	{
		write!(f, "({}, {}, {})", self.x, self.y, self.z)
	}
}

impl Hash for Vector3
{
  fn hash<H: Hasher>(&self, state: &mut H)
  {
    self.x.map::<u32>().unwrap().hash(state);
    self.y.map::<u32>().unwrap().hash(state);
    self.z.map::<u32>().unwrap().hash(state);
  }
}

impl Index<usize> for Vector3
{
	type Output = f32;
	
	fn index<'a>(&'a self, i: usize) -> &'a f32
	{
		match i
		{
			0 => &self.x,
			1 => &self.y,
			2 => &self.z,
			_ => panic!("Vector3::index(): out of bounds: {}", i)
		}
	}
}

impl IndexMut<usize> for Vector3
{
	fn index_mut<'a>(&'a mut self, i: usize) -> &'a mut f32
	{
		match i
		{
			0 => &mut self.x,
			1 => &mut self.y,
			2 => &mut self.z,
			_ => panic!("Vector3::index_mut(): out of bounds: {}", i)
		}
	}
}

impl PartialEq for Vector3
{
	fn eq(&self, other: &Vector3) -> bool
	{
		self.x == other.x && self.y == other.y && self.z == other.z
	}
}

impl PartialOrd for Vector3
{
	fn partial_cmp(&self, other: &Vector3) -> Option<Ordering>
	{
		if self.x < other.x && self.y < other.y && self.z < other.z
		{
			return Some(Ordering::Less);
		}
		else if self.x > other.x && self.y > other.y && self.z > other.z
		{
			return Some(Ordering::Greater);
		}
		else { return Some(Ordering::Equal) }
	}
}

impl Add for Vector3
{
	type Output = Vector3;
	
	fn add(self, rhs: Vector3) -> Vector3
	{
		Vector3
		{
			x: self.x + rhs.x,
			y: self.y + rhs.y,
			z: self.z + rhs.z
		}
	}
}

impl Add<f32> for Vector3
{
	type Output = Vector3;
	
	fn add(self, rhs: f32) -> Vector3
	{
		Vector3
		{
			x: self.x + rhs,
			y: self.y + rhs,
			z: self.z + rhs
		}
	}
}

impl AddAssign for Vector3
{
	fn add_assign(&mut self, rhs: Vector3)
	{
		*self = Vector3
		{
			x: self.x + rhs.x,
			y: self.y + rhs.y,
			z: self.z + rhs.z
		};
	}
}

impl AddAssign<f32> for Vector3
{
	fn add_assign(&mut self, rhs: f32)
	{
		*self = Vector3
		{
			x: self.x + rhs,
			y: self.y + rhs,
			z: self.z + rhs
		};
	}
}

impl Div for Vector3
{
	type Output = Vector3;
	
	fn div(self, rhs: Vector3) -> Vector3
	{
		Vector3
		{
			x: self.x / rhs.x,
			y: self.y / rhs.y,
			z: self.z / rhs.z
		}
	}
}

impl Div<f32> for Vector3
{
	type Output = Vector3;
	
	fn div(self, rhs: f32) -> Vector3
	{
		Vector3
		{
			x: self.x / rhs,
			y: self.y / rhs,
			z: self.z / rhs
		}
	}
}

impl DivAssign for Vector3
{
	fn div_assign(&mut self, rhs: Vector3)
	{
		*self = Vector3
		{
			x: self.x / rhs.x,
			y: self.y / rhs.y,
			z: self.z / rhs.z
		};
	}
}

impl DivAssign<f32> for Vector3
{
	fn div_assign(&mut self, rhs: f32)
	{
		*self = Vector3
		{
			x: self.x / rhs,
			y: self.y / rhs,
			z: self.z / rhs
		};
	}
}

impl Mul for Vector3
{
	type Output = Vector3;
	
	fn mul(self, rhs: Vector3) -> Vector3
	{
		Vector3
		{
			x: self.x * rhs.x,
			y: self.y * rhs.y,
			z: self.z * rhs.z
		}
	}
}

impl Mul<f32> for Vector3
{
	type Output = Vector3;
	
	fn mul(self, rhs: f32) -> Vector3
	{
		Vector3
		{
			x: self.x * rhs,
			y: self.y * rhs,
			z: self.z * rhs
		}
	}
}

impl MulAssign for Vector3
{
	fn mul_assign(&mut self, rhs: Vector3)
	{
		*self = Vector3
		{
			x: self.x * rhs.x,
			y: self.y * rhs.y,
			z: self.z * rhs.z
		};
	}
}

impl MulAssign<f32> for Vector3
{
	fn mul_assign(&mut self, rhs: f32)
	{
		*self = Vector3
		{
			x: self.x * rhs,
			y: self.y * rhs,
			z: self.z * rhs
		};
	}
}

impl Neg for Vector3
{
	type Output = Vector3;
	
	fn neg(self) -> Vector3
	{
		Vector3 { x: -self.x, y: -self.y, z: -self.z }
	}
}

impl Rem for Vector3
{
	type Output = Vector3;
	
	fn rem(self, rhs: Vector3) -> Vector3
	{
		Vector3
		{
			x: self.x % rhs.x,
			y: self.y % rhs.y,
			z: self.z % rhs.z
		}
	}
}

impl Rem<f32> for Vector3
{
	type Output = Vector3;
	
	fn rem(self, rhs: f32) -> Vector3
	{
		Vector3
		{
			x: self.x % rhs,
			y: self.y % rhs,
			z: self.z % rhs
		}
	}
}

impl RemAssign for Vector3
{
	fn rem_assign(&mut self, rhs: Vector3)
	{
		*self = Vector3
		{
			x: self.x % rhs.x,
			y: self.y % rhs.y,
			z: self.z % rhs.z
		};
	}
}

impl RemAssign<f32> for Vector3
{
	fn rem_assign(&mut self, rhs: f32)
	{
		*self = Vector3
		{
			x: self.x % rhs,
			y: self.y % rhs,
			z: self.z % rhs
		};
	}
}

impl Sub for Vector3
{
	type Output = Vector3;
	
	fn sub(self, rhs: Vector3) -> Vector3
	{
		Vector3
		{
			x: self.x - rhs.x,
			y: self.y - rhs.y,
			z: self.z - rhs.z
		}
	}
}

impl Sub<f32> for Vector3
{
	type Output = Vector3;
	
	fn sub(self, rhs: f32) -> Vector3
	{
		Vector3
		{
			x: self.x - rhs,
			y: self.y - rhs,
			z: self.z - rhs
		}
	}
}

impl SubAssign for Vector3
{
	fn sub_assign(&mut self, rhs: Vector3)
	{
		*self = Vector3
		{
			x: self.x - rhs.x,
			y: self.y - rhs.y,
			z: self.z - rhs.z
		};
	}
}

impl SubAssign<f32> for Vector3
{
	fn sub_assign(&mut self, rhs: f32)
	{
		*self = Vector3
		{
			x: self.x - rhs,
			y: self.y - rhs,
			z: self.z - rhs
		};
	}
}

bounding_box

use byteorder::ByteOrder;
use std::cmp::PartialEq;
use std::f32;
use std::fmt;
use std::hash::{Hash,Hasher};
use std::io::{Cursor,Read,Result,Write};

use bounding_sphere::BoundingSphere;
use Containment;
use plane::{Plane,PlaneIntersection};
use ray::Ray;
use vector3::{ReadVector3,Vector3,WriteVector3};

#[derive(Debug, Default, Clone, Copy)]
pub struct BoundingBox
{
	pub min: Vector3,
	pub max: Vector3,
}

impl BoundingBox
{
	pub fn contains_vec(&self, v: Vector3) -> bool
	{
		if v.x < self.min.x || v.x > self.max.x || v.y < self.min.y || v.y > self.max.y ||
			v.z < self.min.z || v.z > self.max.z
		{
			return false;
		}
		
		true
	}
	
	pub fn intersects_box(&self, other: &BoundingBox) -> bool
	{
		self.max.x >= other.min.x && self.min.x <= other.max.x &&
			self.max.y >= other.min.y && self.min.y <= other.max.y &&
			self.max.z >= other.min.z && self.min.z <= other.max.z
	}
	
	pub fn intersects_ray(&self, ray: &Ray) -> Option<f32>
	{
		match ray.intersects_box(self)
		{
			Some(f) => Some(f),
			None => None
		}
	}
	
	pub fn contains_box(&self, other: &BoundingBox) -> Containment
	{
		if self.max.x < other.min.x || self.min.x > other.max.x || self.max.y < other.min.y ||
			self.min.y > other.max.y || self.max.z < other.min.z || self.min.z > other.max.z
		{
			return Containment::Disjoint;
		}
		
		if self.max.x > other.min.x || self.min.x < other.max.x || self.max.y > other.min.y ||
			self.min.y < other.max.y || self.max.z > other.min.z || self.min.z < other.max.z
		{
			return Containment::Intersects;
		}
		
		Containment::Contains
	}
	
	pub fn intersects_plane(&self, p: &Plane) -> PlaneIntersection
	{
		let v = Vector3
		{
			x: if p.normal.x >= 0f32 { self.min.x } else { self.max.x },
			y: if p.normal.y >= 0f32 { self.min.y } else { self.max.y },
			z: if p.normal.z >= 0f32 { self.min.z } else { self.max.z }
		};
		if p.normal.dot(v) + p.distance > 0f32 { return PlaneIntersection::Front; }
		let v = Vector3
		{
			x: if p.normal.x >= 0f32 { self.max.x } else { self.min.x },
			y: if p.normal.y >= 0f32 { self.max.y } else { self.min.y },
			z: if p.normal.z >= 0f32 { self.max.z } else { self.min.z }
		};
		if p.normal.dot(v) + p.distance < 0f32 { return PlaneIntersection::Back; }
		
		PlaneIntersection::Intersecting
	}
	
	pub fn intersects_sphere(&self, bs: &BoundingSphere) -> bool
	{
		bs.center.dist_sq(bs.center.clamp(self.min, self.max)) <= bs.radius * bs.radius
	}
	
	pub fn contains_sphere(&self, bs: &BoundingSphere) -> Containment
	{
		let distsq = bs.center.dist_sq(bs.center.clamp(self.min, self.max));
		if distsq > bs.radius * bs.radius { return Containment::Disjoint; }
		
		if self.min.x + bs.radius > bs.center.x ||
			bs.center.x > self.max.x - bs.radius ||
			self.max.x - self.min.x <= bs.radius ||
			self.min.y + bs.radius > bs.center.y ||
			bs.center.y > self.max.y - bs.radius ||
			self.max.y - self.min.y <= bs.radius ||
			self.min.z + bs.radius > bs.center.z ||
			bs.center.z > self.max.z - bs.radius ||
			self.max.z - self.min.z <= bs.radius
		{
			return Containment::Intersects;
		}
		
		Containment::Contains
	}
	
	pub fn new(center: Vector3, size: f32) -> BoundingBox
	{
		BoundingBox
		{
			min: Vector3
			{
				x: center.x - size,
				y: f32::MIN,
				z: center.z - size
			},
			max: Vector3
			{
				x: center.x + size,
				y: f32::MAX,
				z: center.z + size
			}
		}
	}
}

pub trait ReadBoundingBox: ReadVector3
{
  #[inline]
  fn read_bb<T: ByteOrder>(&mut self) -> Result<BoundingBox>
  {
    let mut buf = Cursor::new(vec![0; 24]);
    self.read_exact(buf.get_mut())?;
    Ok(BoundingBox
    {
      min: buf.read_v3::<T>()?,
      max: buf.read_v3::<T>()?,
    })
  }
}

impl <T: Read + ?Sized> ReadBoundingBox for T {}

pub trait WriteBoundingBox: WriteVector3
{
  #[inline]
  fn write_bb<T: ByteOrder>(&mut self, n: BoundingBox) -> Result<()>
  {
    let mut buf = Cursor::new(vec![0; 24]);
    buf.write_v3::<T>(n.min)?;
    buf.write_v3::<T>(n.max)?;
    self.write_all(&buf)
  }
}

impl <T: Write + ?Sized> WriteBoundingBox for T {}

impl fmt::Display for BoundingBox
{
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
	{
		write!(f, "<{}:{}>", self.min, self.max)
	}
}

impl Hash for BoundingBox
{
  fn hash<H: Hasher>(&self, state: &mut H)
  {
    self.min.hash(state);
    self.max.hash(state);
  }
}

impl PartialEq for BoundingBox
{
	fn eq(&self, other: &BoundingBox) -> bool
	{
		self.min == other.min && self.max == other.max
	}
}

And what error are you getting?

error[E0308]: mismatched types
   --> src/bounding_box.rs:158:20
    |
158 |     self.write_all(&buf)
    |                    ^^^^ expected slice, found struct `std::io::Cursor`
    |
    = note: expected type `&[u8]`
               found type `&std::io::Cursor<std::vec::Vec<u8>>`
    = help: here are some functions which might fulfill your needs:
            - .get_ref()
            - .into_inner()

I don't see anything like this in the example though.

Write in std::io - Rust - notice it needs a &[u8] as a parameter, but you're providing &Cursor<Vec<u8>>. As the compiler helpfully suggests, use buf.get_ref - that returns &Vec<u8> but deref coercion coerces it to &[u8].

Fixed! Appreciated

1 Like