xref: /aosp_15_r20/external/skia/experimental/rust_png/ffi/FFI.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2024 Google LLC.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkRustPngFFI_DEFINED
9 #define SkRustPngFFI_DEFINED
10 
11 #include <stddef.h>
12 #include <stdint.h>
13 
14 // TODO(https://crbug.com/356698922): Use a real `#include` if possible.
15 namespace rust {
16 inline namespace cxxbridge1 {
17 template <typename T> class Slice;
18 }  // namespace cxxbridge1
19 }  // namespace rust
20 
21 namespace rust_png {
22 
23 // Implementing the abstract C++ class below gives a rough equivalent of
24 // `dyn std::io::Read` from Rust.
25 class ReadTrait {
26 public:
27     // The `virtual` method below is a rough equivalent of the
28     // `std::io::Read::read` method in Rust. See
29     // https://doc.rust-lang.org/nightly/std/io/trait.Read.html#tymethod.read
30     // for guidance on the desired implementation and behavior of this method.
31     //
32     // Note that (unlike in Rust) this method is infallible.  This aspect of the
33     // design is used tentatively and based on the following considerations:
34     // * `SkStream::read` is also infallible
35     // * `SkStream::read` communicates no-more-input by reporting that 0 bytes
36     //   have been read (just like Rust's `Read` trait), and this condition
37     //   corresponds to the only IO error covered by `SkCodec::Result`:
38     //   `kIncompleteInput`.
39     // * FFI based on the `cxx` crate doesn't currently support Rust's
40     //   `std::result::Result`, `std::option::Option`, nor C++'s
41     //   `std::optional` or `std::expected`.
42     virtual size_t read(rust::Slice<uint8_t> buffer) = 0;
43 
44     // `drop` is not part of the `std::io::Read` trait, but we expose the
45     // destructor through public API to make it possible to pass
46     // `std::unique_ptr<ReadTrait>` over the FFI boundary.
47     virtual ~ReadTrait() = default;
48 
49     // This type is non-copyable and non-movable.
50     ReadTrait(const ReadTrait&) = delete;
51     ReadTrait(ReadTrait&&) = delete;
52     ReadTrait& operator=(const ReadTrait&) = delete;
53     ReadTrait& operator=(ReadTrait&&) = delete;
54 
55 protected:
56     ReadTrait() = default;
57 };
58 
59 // Implementing the abstract C++ class below gives a rough equivalent of
60 // `dyn std::io::Write` from Rust.
61 class WriteTrait {
62 public:
63     // The `virtual` method below is a rough equivalent of the
64     // `std::io::Write::write` method in Rust. See
65     // https://doc.rust-lang.org/nightly/std/io/trait.Write.html#tymethod.write
66     // for guidance on the desired implementation and behavior of this method.
67     //
68     // Implementation should return `true` if the whole buffer has been
69     // successfully written (and return `false` to indicate an error).
70     // This mimics how `SkStreamW::write` communicates errors.
71     virtual bool write(rust::Slice<const uint8_t> buffer) = 0;
72 
73     // The `virtual` method below is a rough equivalent of the
74     // `std::io::Write::flush` method in Rust. See
75     // https://doc.rust-lang.org/nightly/std/io/trait.Write.html#tymethod.flush
76     // for guidance on the desired implementation and behavior of this method.
77     //
78     // Note that (unlike in Rust) this method is infallible.  This aspect of the
79     // design mimics `SkStreamW::flush`.
80     virtual void flush() = 0;
81 
82     // `drop` is not part of the `std::io::Read` trait, but we expose the
83     // destructor through public API to make it possible to pass
84     // `std::unique_ptr<WriteTrait>` over the FFI boundary.
85     virtual ~WriteTrait() = default;
86 
87     // This type is non-copyable and non-movable.
88     WriteTrait(const WriteTrait&) = delete;
89     WriteTrait(WriteTrait&&) = delete;
90     WriteTrait& operator=(const WriteTrait&) = delete;
91     WriteTrait& operator=(WriteTrait&&) = delete;
92 
93 protected:
94     WriteTrait() = default;
95 };
96 
97 }  // namespace rust_png
98 
99 #endif  // SkRustPngFFI_DEFINED
100