1 use std::ops::{RangeBounds, Bound};
2 
3 use webcore::value::Reference;
4 use webcore::try_from::TryInto;
5 use webcore::reference_type::ReferenceType;
6 use webcore::number::Number;
7 use webcore::optional_arg::OptionalArg;
8 
9 // https://w3c.github.io/FileAPI/#ref-for-dfn-slice
slice_blob< T, U >( blob: &T, range: U, content_type: Option< &str > ) -> Blob where T: IBlob, U: RangeBounds< u64 >10 fn slice_blob< T, U >( blob: &T, range: U, content_type: Option< &str > ) -> Blob
11     where T: IBlob, U: RangeBounds< u64 >
12 {
13     let start: Number = match range.start_bound() {
14         Bound::Included(&n) => n,
15         Bound::Excluded(&n) => n + 1,
16         Bound::Unbounded => 0
17     }.try_into().unwrap();
18 
19     let end: OptionalArg< Number > = match range.end_bound() {
20         Bound::Included(&n) => Some(n + 1),
21         Bound::Excluded(&n) => Some(n),
22         Bound::Unbounded => None
23     }.try_into().unwrap();
24 
25     let content_type: OptionalArg< &str > = content_type.into();
26     let reference = blob.as_ref();
27     js! (
28         return @{reference}.slice(@{start}, @{end}, @{content_type});
29     ).try_into().unwrap()
30 }
31 
32 /// A blob object represents a file-like object of immutable, raw data.
33 /// Blobs represent data that isn't necessarily in a JavaScript-native format.
34 ///
35 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Blob)
36 // https://w3c.github.io/FileAPI/#dfn-Blob
37 pub trait IBlob: ReferenceType {
38     /// The size, in bytes, of the data contained in the Blob object.
39     ///
40     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Blob/size)
41     // https://w3c.github.io/FileAPI/#ref-for-dfn-size%E2%91%A0
len( &self ) -> u6442     fn len( &self ) -> u64 {
43         let reference = self.as_ref();
44         let length: u64 = js!( return @{reference}.size; ).try_into().unwrap();
45         length
46     }
47 
48     /// A string indicating the MIME type of the data contained in the `Blob`.
49     ///
50     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Blob/type)
51     // https://w3c.github.io/FileAPI/#ref-for-dfn-type%E2%91%A0
mime( &self ) -> Option< String >52     fn mime( &self ) -> Option< String > {
53         let reference = self.as_ref();
54         let mime: String = js!( return @{reference}.type; ).try_into().unwrap();
55         if mime.is_empty() {
56             None
57         } else {
58             Some( mime )
59         }
60     }
61 
62     /// Create a new `Blob` object containing the data in the specified range of bytes of the
63     /// source `Blob`.
64     ///
65     /// See also [slice_with_content_type](IBlob::slice_with_content_type).
66     ///
67     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Blob/slice)
slice< T >( &self, range: T ) -> Blob where T: RangeBounds<u64>68     fn slice< T >( &self, range: T ) -> Blob
69         where T: RangeBounds<u64>
70     {
71         slice_blob(self, range, None)
72     }
73 
74     /// [slice](IBlob::slice) `Blob` with the provided `content_type`.
slice_with_content_type< T >( &self, range: T, content_type: &str ) -> Blob where T: RangeBounds<u64>75     fn slice_with_content_type< T >( &self, range: T, content_type: &str ) -> Blob
76         where T: RangeBounds<u64>
77     {
78         slice_blob(self, range, Some(content_type))
79     }
80 }
81 
82 /// A reference to a JavaScript object which implements the [IBlob](trait.IBlob.html)
83 /// interface.
84 ///
85 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Blob)
86 // https://w3c.github.io/FileAPI/#dfn-Blob
87 #[derive(Clone, Debug, PartialEq, Eq, ReferenceType)]
88 #[reference(instance_of = "Blob")]
89 pub struct Blob( Reference );
90 
91 impl IBlob for Blob {}
92 
93 impl Blob {
94     /// Creates a new `Blob`.
95     ///
96     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob)
97     // https://w3c.github.io/FileAPI/#constructorBlob
new() -> Self98     pub fn new() -> Self {
99         js! (
100             return new Blob();
101         ).try_into().unwrap()
102     }
103 }
104