memfile.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package memfile
  2. import (
  3. "iter"
  4. "maps"
  5. "time"
  6. )
  7. // MemoryFile represents a file in memory storage. It's part of the directory tree
  8. // structure used to look up files by path.
  9. type MemoryFile struct {
  10. Name string
  11. Contents []byte
  12. ModTime time.Time
  13. directory *MemoryDirectory
  14. }
  15. // Size returns the size of the file in bytes.
  16. func (mf *MemoryFile) Size() int64 {
  17. return int64(len(mf.Contents))
  18. }
  19. // NewMemoryFile creates a new MemoryFile instance with the provided name and and byte contents.
  20. func NewMemoryFile(name string, contents []byte) *MemoryFile {
  21. return &MemoryFile{
  22. Name: name,
  23. Contents: contents,
  24. ModTime: time.Now().UTC(),
  25. directory: nil,
  26. }
  27. }
  28. // MemoryDirectory represents a directory in memory storage. It is the root of the file system
  29. // tree structure used to look up files by path.
  30. type MemoryDirectory struct {
  31. Name string
  32. ModTime time.Time
  33. dirs map[string]*MemoryDirectory
  34. files map[string]*MemoryFile
  35. directory *MemoryDirectory
  36. }
  37. // NewMemoryDirectory creates a new Directory instance with the provided path name.
  38. func NewMemoryDirectory(name string) *MemoryDirectory {
  39. return &MemoryDirectory{
  40. Name: name,
  41. dirs: make(map[string]*MemoryDirectory),
  42. files: make(map[string]*MemoryFile),
  43. }
  44. }
  45. // Size returns the size of all subdirectories and files within this directory.
  46. func (d *MemoryDirectory) Size() int64 {
  47. var size int64
  48. for _, f := range d.files {
  49. size += f.Size()
  50. }
  51. for _, subdir := range d.dirs {
  52. size += subdir.Size()
  53. }
  54. return size
  55. }
  56. // AddFile adds a file to the directory. Note that files can only exist within a single directory
  57. // at a time.
  58. func (d *MemoryDirectory) AddFile(f *MemoryFile) {
  59. if f.directory != nil {
  60. f.directory.RemoveFile(f.Name)
  61. f.directory = nil
  62. }
  63. d.files[f.Name] = f
  64. d.ModTime = time.Now().UTC()
  65. f.directory = d
  66. }
  67. // AddDirectory adds a subdirectory to the parent directory. Note that directories can only exist within a single directory.
  68. func (d *MemoryDirectory) AddDirectory(subdir *MemoryDirectory) {
  69. if subdir.directory != nil {
  70. subdir.directory.RemoveDirectory(subdir.Name)
  71. subdir.directory = nil
  72. }
  73. d.dirs[subdir.Name] = subdir
  74. d.ModTime = time.Now().UTC()
  75. subdir.directory = d
  76. }
  77. // RemoveFile removes a file from the directoory tree.
  78. func (d *MemoryDirectory) RemoveFile(name string) {
  79. if _, ok := d.files[name]; ok {
  80. delete(d.files, name)
  81. d.ModTime = time.Now().UTC()
  82. }
  83. }
  84. // RemoveDirectory remove a subdirectory from the directory tree.
  85. func (d *MemoryDirectory) RemoveDirectory(name string) {
  86. if _, ok := d.dirs[name]; ok {
  87. delete(d.dirs, name)
  88. d.ModTime = time.Now().UTC()
  89. }
  90. }
  91. // FileCount returns the total number of files in this directory.
  92. func (d *MemoryDirectory) FileCount() int {
  93. return len(d.files)
  94. }
  95. // DirCount returns the total number of subdirectories in this directory.
  96. func (d *MemoryDirectory) DirCount() int {
  97. return len(d.dirs)
  98. }
  99. // Files returns a slice of files located within this directory.
  100. func (d *MemoryDirectory) Files() iter.Seq[*MemoryFile] {
  101. return maps.Values(d.files)
  102. }
  103. func (d *MemoryDirectory) Directories() iter.Seq[*MemoryDirectory] {
  104. return maps.Values(d.dirs)
  105. }