1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
#[cfg(feature = "model")] use hyper::Client as HyperClient; #[cfg(feature = "model")] use std::io::Read; #[cfg(feature = "model")] use internal::prelude::*; /// A file uploaded with a message. Not to be confused with [`Embed`]s. /// /// [`Embed`]: struct.Embed.html #[derive(Clone, Debug, Deserialize)] pub struct Attachment { /// The unique ID given to this attachment. pub id: String, /// The filename of the file that was uploaded. This is equivalent to what /// the uploader had their file named. pub filename: String, /// If the attachment is an image, then the height of the image is provided. pub height: Option<u64>, /// The proxy URL. pub proxy_url: String, /// The size of the file in bytes. pub size: u64, /// The URL of the uploaded attachment. pub url: String, /// If the attachment is an image, then the width of the image is provided. pub width: Option<u64>, } #[cfg(feature = "model")] impl Attachment { /// If this attachment is an image, then a tuple of the width and height /// in pixels is returned. pub fn dimensions(&self) -> Option<(u64, u64)> { self.width .and_then(|width| self.height.map(|height| (width, height))) } /// Downloads the attachment, returning back a vector of bytes. /// /// # Examples /// /// Download all of the attachments associated with a [`Message`]: /// /// ```rust,no_run /// use serenity::prelude::*; /// use serenity::model::*; /// use std::env; /// use std::fs::File; /// use std::io::Write; /// use std::path::Path; /// /// struct Handler; /// /// /// impl EventHandler for Handler { /// fn on_message(&self, _: Context, message: Message) { /// for attachment in message.attachments { /// let content = match attachment.download() { /// Ok(content) => content, /// Err(why) => { /// println!("Error downloading attachment: {:?}", why); /// let _ = message.channel_id.say("Error downloading attachment"); /// /// return; /// }, /// }; /// /// let mut file = match File::create(&attachment.filename) { /// Ok(file) => file, /// Err(why) => { /// println!("Error creating file: {:?}", why); /// let _ = message.channel_id.say("Error creating file"); /// /// return; /// }, /// }; /// /// if let Err(why) = file.write(&content) { /// println!("Error writing to file: {:?}", why); /// /// return; /// } /// /// let _ = message.channel_id.say(&format!("Saved {:?}", attachment.filename)); /// } /// } /// /// fn on_ready(&self, _: Context, ready: Ready) { /// println!("{} is connected!", ready.user.name); /// } /// } /// let token = env::var("DISCORD_TOKEN").expect("token in environment"); /// let mut client = Client::new(&token, Handler); client.start().unwrap(); /// ``` /// /// # Errors /// /// Returns an [`Error::Io`] when there is a problem reading the contents /// of the HTTP response. /// /// Returns an [`Error::Hyper`] when there is a problem retrieving the /// attachment. /// /// [`Error::Hyper`]: ../enum.Error.html#variant.Hyper /// [`Error::Io`]: ../enum.Error.html#variant.Io /// [`Message`]: struct.Message.html pub fn download(&self) -> Result<Vec<u8>> { let hyper = request_client!(); let mut response = hyper.get(&self.url).send()?; let mut bytes = vec![]; response.read_to_end(&mut bytes)?; Ok(bytes) } }