afs.rs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. use crate::error::{MountError, AfsFreeError, AfsMkdirError};
  2. use crate::raw_fn;
  3. /// Afs Instance
  4. pub struct AfsInstance (i32);
  5. impl AfsInstance {
  6. /// Create a new AfsInstance from raw handle
  7. pub fn new_from_handle(handle: i32) -> Self {
  8. Self(handle)
  9. }
  10. /// Mount the AfsInstance to specified mount point
  11. pub fn mount(&self, mnt_path: &str) -> Result<(), MountError> {
  12. let r = unsafe {
  13. raw_fn::vfs_mount(self.0, mnt_path.as_ptr(), mnt_path.len())
  14. };
  15. match r {
  16. 0 => Ok(()),
  17. -1 => Err(MountError::InvalidAfsHandle),
  18. -2 => Err(MountError::InternalError(
  19. String::from("vfs_mount: reading MntPath from memory out of bounds")
  20. )),
  21. -3 => Err(MountError::MountPointAlreadyMounted),
  22. -4 => Err(MountError::InternalError(
  23. String::from("vfs_mount: reading MntPath from memory out of bounds")
  24. )),
  25. _ => Err(MountError::InternalError(
  26. format!("vfs_mount: unknown error: code = {}", r)
  27. )),
  28. }
  29. }
  30. /// Free the AfsInstance
  31. /// The lifecycle of wasm_init is shorter than the lifecycle of the entire ngvfs,
  32. /// so we can't utilize Rust's Drop trait to automatically release the AfsInstance object,
  33. /// and you need to manually call free to release it if there is an unneeded AfsInstance object.
  34. /// After this free function has been called, do not use this object again.
  35. pub fn free(&self) -> Result<(), AfsFreeError> {
  36. let r = unsafe {
  37. raw_fn::afs_free(self.0)
  38. };
  39. match r {
  40. 0 => Ok(()),
  41. -1 => Err(AfsFreeError::InvalidAfsHandle),
  42. _ => Err(AfsFreeError::InternalError(
  43. format!("vfs_free: unknown error: code = {}", r)
  44. ))
  45. }
  46. }
  47. pub fn get_handle_value(&self) -> i32 {
  48. self.0
  49. }
  50. /// Create directory on AfsInstance. Works like `mkdir -p`.
  51. pub fn mkdir(&self, path: &str, mode: i32) -> Result<(), AfsMkdirError> {
  52. let r = unsafe {
  53. raw_fn::afs_mkdir(self.0, path.as_ptr(), path.len(), mode)
  54. };
  55. match r {
  56. 0 => Ok(()),
  57. -2 => Err(AfsMkdirError::InvalidAfsHandle),
  58. -3 => Err(AfsMkdirError::InternalError(
  59. String::from("afs_mkdir: reading path from memory out of bounds")
  60. )),
  61. -1 => Err(AfsMkdirError::InternalError(
  62. String::from("afs_mkdir: failed create directory: see logs.")
  63. )),
  64. _ => Err(AfsMkdirError::InternalError(
  65. format!("afs_mkdir: unknown error: code = {}", r)
  66. )),
  67. }
  68. }
  69. /// New afero.OsFs Instance
  70. pub fn new_afero_osfs() -> Self {
  71. let r = unsafe {
  72. raw_fn::afs_create_osfs()
  73. };
  74. if r > 0 {
  75. Self(r)
  76. }else{
  77. panic!("failed to create afero.OsFs: err_code={}", r)
  78. }
  79. }
  80. /// New afero.MemFs Instance
  81. pub fn new_afero_memfs() -> Self {
  82. let r = unsafe {
  83. raw_fn::afs_create_memfs()
  84. };
  85. if r > 0 {
  86. Self(r)
  87. }else{
  88. panic!("failed to create afero.MemFs: err_code={}", r)
  89. }
  90. }
  91. /// New afero.BasePathFs Instance.
  92. pub fn new_afero_bpfs(base_fs: &AfsInstance, base_path: &str) -> Self {
  93. let r = unsafe {
  94. raw_fn::afs_create_bpfs(base_fs.0, base_path.as_ptr(), base_path.len())
  95. };
  96. if r > 0 {
  97. Self(r)
  98. }else{
  99. panic!("failed to create afero.BasePathFs: err_code={}", r)
  100. }
  101. }
  102. /// New afero.RegexpFs Instance
  103. pub fn new_afero_regfs(base_fs: &AfsInstance, regexp: &str) -> Self {
  104. let r = unsafe {
  105. raw_fn::afs_create_regfs(base_fs.0, regexp.as_ptr(), regexp.len())
  106. };
  107. if r > 0 {
  108. Self(r)
  109. }else{
  110. panic!("failed to create afero.RegexpFs: err_code={}", r)
  111. }
  112. }
  113. /// New afero.ReadOnlyFs Instance
  114. pub fn new_afero_rofs(base_fs: &AfsInstance) -> Self {
  115. let r = unsafe {
  116. raw_fn::afs_create_rofs(base_fs.0)
  117. };
  118. if r > 0 {
  119. Self(r)
  120. }else{
  121. panic!("failed to create afero.ReadOnlyFs: err_code={}", r)
  122. }
  123. }
  124. /// New afero.CopyOnWriteFs Instance
  125. pub fn new_afero_cowfs(base_ro_fs: &AfsInstance, base_wr_fs: &AfsInstance) -> Self {
  126. let r = unsafe {
  127. raw_fn::afs_create_cowfs(base_ro_fs.0, base_wr_fs.0)
  128. };
  129. if r > 0 {
  130. Self(r)
  131. }else{
  132. panic!("failed to create afero.CopyOnWriteFs: err_code={}", r)
  133. }
  134. }
  135. /// New afero.CacheOnReadFs Instance. cacheSeconds is the cache time in seconds.
  136. /// if cache_time_secs == 0, cache is permanent.
  137. /// if cache_time_secs < 0, will cause error.
  138. pub fn new_afero_corfs(base_ro_fs: &AfsInstance, base_wr_fs: &AfsInstance, cache_time_secs: i32) -> Self {
  139. let r = unsafe {
  140. raw_fn::afs_create_corfs(base_ro_fs.0, base_wr_fs.0, cache_time_secs)
  141. };
  142. if r > 0 {
  143. Self(r)
  144. }else{
  145. panic!("failed to create afero.CacheOnReadFs: err_code={}", r)
  146. }
  147. }
  148. }