vfs.vfs_contacts #
Contacts VFS Module
This module contains the Virtual File System (VFS) implementation for the Contacts component of the MCC (Mail, Contacts, Calendar) system, built in the V programming language. The Contacts VFS provides a read-only interface to browse and access contact data in a file system-like structure, which can be mounted and accessed via protocols like WebDAV.
Table of Contents
Overview
The Contacts VFS implementation provides a read-only virtual file system interface to the contacts backend service. It organizes contact data hierarchically, with contact groups as directories and individual contacts as JSON files. Contacts can be browsed by name or email, making it easy to integrate with tools that support file system protocols such as WebDAV.
Features
- Consistent Interface: Adheres to the
vfs.VFS
interface defined in/lib/vfs/interface.v
, ensuring compatibility with other MCC VFS implementations. - Read-Only Access: Provides read-only access to contact data, with plans for future write support.
- Structured Data Access:
- Organizes contact groups as directories.
- Represents individual contacts as JSON files.
- Allows browsing by name (
by_name
) and email (by_email
). - Comprehensive Testing: Includes unit tests to verify functionality.
- Error Handling: Gracefully handles errors for invalid paths, non-existent entries, and unsupported operations.
Usage
The Contacts VFS organizes contact groups as directories, with contacts as JSON files, browsable by name and email.
Example Structure:
/personal/
├── by_name/
│ └── john_doe.json
├── by_email/
│ └── john_doe_example_com.json
/work/
├── by_name/
│ └── jane_smith.json
├── by_email/
│ └── jane_smith_example_com.json
Usage Example:
import freeflowuniverse.herolib.vfs
import vfs_contacts
import freeflowuniverse.herolib.circles.dbs.core
fn main() ! {
// Setup mock database
mut contacts_db := core.new_mock_contacts_db()
contact1 := contacts.Contact{
id: 1
first_name: 'John'
last_name: 'Doe'
email: 'john.doe@example.com'
group: 'personal'
created_at: 1698777600
modified_at: 1698777600
}
contact2 := contacts.Contact{
id: 2
first_name: 'Said'
last_name: 'Moaawad'
email: 'said.moaawad@example.com'
group: 'personal'
created_at: 1698777600
modified_at: 1698777600
}
// Add contacts to the database
contacts_db.set(contact1) or { panic(err) }
contacts_db.set(contact2) or { panic(err) }
// Create VFS instance
mut contacts_vfs := new(&contacts_db) or { panic(err) }
// List groups at root
groups := contacts_vfs.dir_list('')!
for group in groups {
println('Group: ${group.metadata.name}')
}
// List contacts in personal group by name
contacts_by_name := contacts_vfs.dir_list('personal/by_name')!
for contact in contacts_by_name {
println('Contact: ${contact.metadata.name}')
}
// Read a contact
contact_data := contacts_vfs.file_read('personal/by_name/john_doe.json')!
println('Contact content: ${contact_data.bytestr()}')
// Check if a contact exists
exists := contacts_vfs.exists('personal/by_email/john_doe_example_com.json')
println('Contact exists: ${exists}')
}
Key Methods
dir_list(path string) ![]vfs.FSEntry
: Lists the contents of a directory (e.g., groups, subdirectories, or contact files).file_read(path string) ![]u8
: Reads the JSON content of a contact file.exists(path string) bool
: Checks if a path (group, subdirectory, or contact file) exists.get(path string) !vfs.FSEntry
: Retrieves metadata for a path.
Notes
- All paths are case-sensitive and use forward slashes (
/
). - Contact file names are normalized using
texttools.name_fix
to ensure valid file system names (e.g., replacing special characters).
Testing
The Contacts VFS implementation includes comprehensive unit tests in the vfs_implementation_test.v
file. To run the tests:
- Navigate to the Module Directory:
cd lib/vfs/vfs_contacts/
- Run Tests:
v test .
The tests cover:- Listing groups, subdirectories, and contact files
- Reading contact file contents
- Existence checks
- Error handling for invalid paths and unsupported operations
fn new #
fn new(contacts_db &core.ContactsDB) !vfs.VFSImplementation
new creates a new contacts_db VFS instance
fn new_contacts_vfs #
fn new_contacts_vfs(contacts_db &core.ContactsDB) !vfs.VFSImplementation
new_contacts_vfs creates a new contacts VFS
struct ContactsFSEntry #
struct ContactsFSEntry {
pub mut:
path string
metadata vfs.Metadata
contact ?contacts.Contact
}
ContactsFSEntry implements FSEntry for contacts objects
fn (ContactsFSEntry) is_dir #
fn (self &ContactsFSEntry) is_dir() bool
is_dir returns true if the entry is a directory
fn (ContactsFSEntry) is_file #
fn (self &ContactsFSEntry) is_file() bool
is_file returns true if the entry is a file
fn (ContactsFSEntry) is_symlink #
fn (self &ContactsFSEntry) is_symlink() bool
is_symlink returns true if the entry is a symlink
fn (ContactsFSEntry) get_metadata #
fn (e ContactsFSEntry) get_metadata() vfs.Metadata
fn (ContactsFSEntry) get_path #
fn (e ContactsFSEntry) get_path() string
struct ContactsVFS #
struct ContactsVFS {
pub mut:
contacts_db &core.ContactsDB // Reference to the contacts database
}
ContactsVFS represents the virtual file system for contacts
fn (ContactsVFS) copy #
fn (mut myvfs ContactsVFS) copy(src_path string, dst_path string) !vfs.FSEntry
fn (ContactsVFS) delete #
fn (mut myvfs ContactsVFS) delete(path string) !
fn (ContactsVFS) destroy #
fn (mut myvfs ContactsVFS) destroy() !
Cleanup operation
fn (ContactsVFS) dir_create #
fn (mut myvfs ContactsVFS) dir_create(path string) !vfs.FSEntry
Directory operations
fn (ContactsVFS) dir_delete #
fn (mut myvfs ContactsVFS) dir_delete(path string) !
fn (ContactsVFS) dir_list #
fn (mut myvfs ContactsVFS) dir_list(path string) ![]vfs.FSEntry
fn (ContactsVFS) exists #
fn (mut myvfs ContactsVFS) exists(path string) bool
Common operations
fn (ContactsVFS) file_concatenate #
fn (mut myvfs ContactsVFS) file_concatenate(path string, data []u8) !
fn (ContactsVFS) file_create #
fn (mut myvfs ContactsVFS) file_create(path string) !vfs.FSEntry
File operations
fn (ContactsVFS) file_delete #
fn (mut myvfs ContactsVFS) file_delete(path string) !
fn (ContactsVFS) file_read #
fn (mut myvfs ContactsVFS) file_read(path string) ![]u8
fn (ContactsVFS) file_write #
fn (mut myvfs ContactsVFS) file_write(path string, data []u8) !
fn (ContactsVFS) get #
fn (mut myvfs ContactsVFS) get(path string) !vfs.FSEntry
fn (ContactsVFS) get_path #
fn (mut myvfs ContactsVFS) get_path(entry &vfs.FSEntry) !string
FSEntry Operations
fn (ContactsVFS) link_create #
fn (mut myvfs ContactsVFS) link_create(target_path string, link_path string) !vfs.FSEntry
Symlink operations
fn (ContactsVFS) link_delete #
fn (mut myvfs ContactsVFS) link_delete(path string) !
fn (ContactsVFS) link_read #
fn (mut myvfs ContactsVFS) link_read(path string) !string
fn (ContactsVFS) move #
fn (mut myvfs ContactsVFS) move(src_path string, dst_path string) !vfs.FSEntry
fn (ContactsVFS) print #
fn (mut myvfs ContactsVFS) print() !
fn (ContactsVFS) rename #
fn (mut myvfs ContactsVFS) rename(old_path string, new_path string) !vfs.FSEntry
fn (ContactsVFS) root_get #
fn (mut myvfs ContactsVFS) root_get() !vfs.FSEntry
Basic operations