Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2019
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.23 KB | None | 0 0
  1. First we have `FileList` which is simply a list of `File`s. This is an opaque struct that offers a way to iterate over `Files` and get individual files by index:
  2.  
  3. ```rust
  4. #[derive(Debug, Clone)]
  5. struct FileList { ... }
  6.  
  7. impl FileList {
  8. fn get(index: usize) -> Option<File> { ... }
  9.  
  10. fn len(&self) -> usize { ... }
  11.  
  12. fn iter(&self) -> FileListIter { ... }
  13.  
  14. fn as_raw(&self) -> &web_sys::FileList { ... }
  15. }
  16.  
  17. impl AsRef<web_sys::FileList> for FileList { ... }
  18. impl From<web_sys::FileList> for FileList { ... }
  19. impl Index<usize> for FileList {
  20. type Output = File;
  21. fn index(&self, index: usize) -> &Self::Output { ... }
  22. }
  23. ```
  24.  
  25. There is no `FileList::new` since creating a raw `web_sys::FileList` is not possible without going through a `web_sys::HtmlInputElement`.
  26.  
  27. Next we have a `blob` module that includes the trait `BlobLike`
  28. ```rust
  29. trait BlobLike {
  30. fn size(&self) -> u64 { ... }
  31.  
  32. // the mime crate and mimes from blobs both conform to rfc6838
  33. #[cfg(feature = "mime")]
  34. fn mime_type(&self) -> Result<mime::Mime, mime::FromStrError> { ... }
  35.  
  36. fn raw_mime_type(&self) -> String { ... }
  37.  
  38. fn as_raw(&self) -> &web_sys::Blob;
  39. }
  40. ```
  41. There are two structs that implement this trait: `Blob` and `File`.
  42.  
  43. ```rust
  44. #[derive(Debug, Clone)]
  45. struct Blob { ... }
  46.  
  47. impl Blob {
  48. fn new<T>(content: T) -> Blob
  49. where
  50. T: std::convert::Into<BlobContents> // We'll look at BlobContents below
  51. { ... }
  52.  
  53. fn new_with_options<T>(content: T, mime_type: Option<String>) -> Blob
  54. where
  55. T: std::convert::Into<BlobContents>
  56. { ... }
  57.  
  58. fn slice(&self, start: usize, end: usize) -> Blob { ... }
  59. }
  60.  
  61. impl From<web_sys::Blob> for Blob { ... }
  62.  
  63.  
  64. impl BlobLike for Blob { ... }
  65.  
  66. #[derive(Debug, Clone)]
  67. pub struct File { ... }
  68.  
  69. impl File {
  70. fn new<T>(
  71. name: String,
  72. contents: Option<T>,
  73. mime_type: Option<String>,
  74. last_modified_date: Option<u64>,
  75. ) -> File
  76. where
  77. T: std::convert::Into<BlobContents>,
  78. { ... }
  79.  
  80. fn name(&self) -> String { ... }
  81.  
  82. fn last_modified_date(&self) -> u64 { ... }
  83.  
  84. fn slice(&self, start: usize, end: usize) -> File { ... }
  85.  
  86. fn as_blob(self) -> Blob { ... }
  87. }
  88.  
  89. impl BlobLike for File { ... }
  90. ```
  91.  
  92. Both Blob and File come with builders that allow for creating new Blobs and Files in the builder style and not having to use `new` directly.
  93.  
  94. `BlobContents` is simply a new-type around `wasm_bindgen::JsValue`s that can be used as the content of `Blob`s and `File`s:
  95.  
  96. ```rust
  97. #[derive(Debug, Clone)]
  98. pub struct BlobContents {
  99. inner: wasm_bindgen::JsValue,
  100. }
  101. ```
  102.  
  103. There are there conversions from types into `BlobContents` only for the types that make sense:
  104.  
  105. ```rust
  106. impl std::convert::Into<BlobContents> for &str
  107. impl std::convert::Into<BlobContents> for &[u8]
  108. impl std::convert::Into<BlobContents> for Blob
  109. impl std::convert::Into<BlobContents> for js_sys::ArrayBuffer
  110. ```
  111.  
  112. Lastly there's the `FileReader` which allows reading from BlobLike objects. We'll have two implementations of this, one based on callbacks and the other based on futures.
  113.  
  114. The callbacks implementation has three categories of callbacks: start, progress and read. Start and progress callbacks are directly related to the `onloadstart` and `onprogress` callbacks on `web_sys::FileReader`. The read varierty of callbacks, are a combination of `onload`, `onloadend`, `onloaderror`, and `onabort`. The callback receives a result which is an error if the underlying read was aborted or errored.
  115.  
  116. The futures implementation likewise exposes success, error, and abort through the fact that futures are `Result`-like. Progress events are exposed as a stream. In the future, we may expose the entire lifecycle of a read through a stream.
  117.  
  118. ```rust
  119. mod callbacks {
  120. #[derive(Debug)]
  121. pub struct FileReader { ... }
  122.  
  123. impl FileReader {
  124. fn new() -> FileReader { ... }
  125.  
  126. fn read_as_string<F>(self, blob: &impl BlobLike, callback: F)
  127. where F: FnOnce(Result<String, FileReadError>) { ... };
  128.  
  129. fn read_as_data_url<F>(self, blob: &impl BlobLike, callback: F)
  130. where F: FnOnce(Result<String, FileReadError>) { ... };
  131.  
  132. fn read_as_array_buffer<F>(self, blob: &impl BlobLike, callback: F)
  133. where F: FnOnce(Result<&web_sys::ArrayBuffer, FileReadError>) { ... };
  134.  
  135. fn on_progress<F>(&mut self, callback: F)
  136. where F: FnMut(ProgressEvent) + 'static { ... }
  137.  
  138. fn on_load_start<F>(&mut self, callback: F)
  139. where F: FnOnce(LoadStartEvent) + 'static { ... }
  140. }
  141. }
  142.  
  143. mod futures {
  144. #[derive(Debug)]
  145. pub struct FileReader { ... }
  146.  
  147. impl FileReader {
  148. fn new() -> FileReader { ... }
  149.  
  150. fn read_as_string(self, blob: &impl BlobLike) -> ReadAs<String> { ... }
  151.  
  152. fn read_as_data_url(self, blob: &impl BlobLike) -> ReadAs<String> { ... }
  153.  
  154. fn read_as_array_buffer(self, blob: &impl BlobLike) -> ReadAs<js_sys::ArrayBuffer>
  155.  
  156. fn on_progress(&self) -> OnProgressStream { }
  157.  
  158. fn on_load_start(&self) -> OnLoadStartFuture { }
  159. }
  160.  
  161. pub struct ReadAs<T> { ... }
  162. impl<T> Future for ReadAs<T> {
  163. type Item = T;
  164. type Error = FileReadError;
  165. ...
  166. }
  167.  
  168. // Make sure that dropping the Future properly aborts the reading
  169. impl<T> std::ops::Drop for ReadAs<T> {
  170. fn drop(&mut self) {
  171. if self.inner.ready_state() < 2 {
  172. self.inner.abort();
  173. }
  174. }
  175. }
  176. }
  177. ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement