| Crates.io | megalib |
| lib.rs | megalib |
| version | 0.5.0 |
| created_at | 2026-01-12 13:45:14.261459+00 |
| updated_at | 2026-01-25 18:03:26.137854+00 |
| description | Rust client library for Mega.nz cloud storage |
| homepage | |
| repository | https://github.com/11philip22/megalib |
| max_upload_size | |
| id | 2037741 |
| size | 403,933 |
A Rust client library for the MEGA cloud storage service.
This library provides a clean, asynchronous Rust interface for interacting with MEGA, supporting authentication, filesystem access, and file management.
Authentication:
change_password)Filesystem:
stat)mkdir)rm)rename)mv)open_folder)File Transfer:
export, export_many)Node Operations:
Sharing & Contacts:
share_folder)list_contacts)Add this to your Cargo.toml:
[dependencies]
megalib = "0.1.0"
tokio = { version = "1", features = ["full"] }
use megalib::session::registration::{register, verify_registration};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Step 1: Initiate registration
let state = register("newuser@example.com", "MySecretPassword", "New User").await?;
println!("Registration initiated! Check your email for the confirmation link.");
// Save state string to use after user clicks the link
let state_str = state.serialize();
// ... User clicks link ...
// Step 2: Complete registration with the link
let link = "https://mega.nz/#confirm..."; // From email
let restored_state = megalib::session::registration::RegistrationState::deserialize(&state_str)?;
verify_registration(&restored_state, link).await?;
println!("Account verified successfully!");
Ok(())
}
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let session = Session::login("user@example.com", "password").await?;
println!("Logged in as: {}", session.email);
Ok(())
}
The library supports HTTP, HTTPS, and SOCKS5 proxies.
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Use a SOCKS5 proxy
let session = Session::login_with_proxy(
"user@example.com",
"password",
"socks5://127.0.0.1:9050"
).await?;
println!("Logged in via proxy as: {}", session.email);
Ok(())
}
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut session = Session::login("user@example.com", "old_password").await?;
session.change_password("new_secure_password").await?;
println!("Password changed successfully!");
Ok(())
}
Save your session to avoid logging in every time.
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Load from file if exists
let mut session = match Session::load("session.json").await? {
Some(s) => s,
None => {
// Fallback to login
let s = Session::login("user@example.com", "password").await?;
s.save("session.json")?;
s
}
};
// Validate session
session.refresh().await?;
Ok(())
}
When loading a cached session, you can optionally specify a proxy to use for the restored session.
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut session = match Session::load_with_proxy("session.json", "http://proxy:8080").await? {
Some(s) => s,
None => {
// Login with proxy if no cache
let s = Session::login_with_proxy("user@example.com", "password", "http://proxy:8080").await?;
s.save("session.json")?;
s
}
};
session.refresh().await?;
Ok(())
}
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut session = Session::login("user@example.com", "password").await?;
session.refresh().await?;
// List root directory
let nodes = session.list("/", false)?;
for node in nodes {
println!("- {} ({} bytes)", node.name, node.size);
}
// Get info for a specific file
if let Some(node) = session.stat("/Root/Documents/Report.pdf") {
println!("Found file: {}", node.name);
}
Ok(())
}
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut session = Session::login("user@example.com", "password").await?;
session.refresh().await?;
// Create directory
session.mkdir("/Root/Project").await?;
// Move a file
session.mv("/Root/draft.txt", "/Root/Project").await?;
// Rename a file
session.rename("/Root/Project/draft.txt", "final.txt").await?;
// Delete a file
session.rm("/Root/Project/old_notes.txt").await?;
Ok(())
}
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut session = Session::login("user@example.com", "password").await?;
let quota = session.quota().await?;
println!("Used: {} / {} bytes ({:.1}%)",
quota.used, quota.total, quota.usage_percent());
println!("Free: {} bytes", quota.free());
Ok(())
}
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut session = Session::login("user@example.com", "password").await?;
session.refresh().await?;
for node in session.list("/Root", true)? {
if node.is_file() {
println!("File: {} ({} bytes)", node.name, node.size);
} else if node.is_folder() {
println!("Folder: {}/", node.name);
}
// Check if already exported
if node.is_exported() {
if let Some(url) = node.get_link(true) {
println!(" Public link: {}", url);
}
}
}
Ok(())
}
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut session = Session::login("user@example.com", "password").await?;
session.refresh().await?;
// Get node by handle (useful for API integrations)
if let Some(node) = session.get_node_by_handle("ABC123xyz") {
println!("Found: {}", node.name);
}
// Check if a node is inside a folder
let file = session.stat("/Root/Documents/report.pdf").unwrap();
let folder = session.stat("/Root/Documents").unwrap();
if session.node_has_ancestor(file, folder) {
println!("File is inside Documents folder");
}
// Check if node is writable
if file.is_writable() {
println!("Can modify this file");
}
Ok(())
}
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut session = Session::login("user@example.com", "password").await?;
session.refresh().await?;
// List users who have shared files with you
for contact in session.list_contacts() {
println!("Contact: {} ({})", contact.name, contact.handle);
}
Ok(())
}
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut session = Session::login("user@example.com", "password").await?;
session.refresh().await?;
let node = session.upload("local_file.txt", "/Root/Project").await?;
println!("Uploaded: {}", node.name);
Ok(())
}
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut session = Session::login("user@example.com", "password").await?;
session.refresh().await?;
// Enable automatic thumbnail generation for images/videos
session.enable_previews(true);
// Upload will now generate and attach thumbnails
let node = session.upload("photo.jpg", "/Root/Photos").await?;
println!("Uploaded with thumbnail: {}", node.name);
Ok(())
}
use megalib::Session;
use std::fs::File;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut session = Session::login("user@example.com", "password").await?;
session.refresh().await?;
if let Some(node) = session.stat("/Root/Project/final.txt").cloned() {
let mut file = File::create("downloaded_final.txt")?;
session.download(&node, &mut file).await?;
}
Ok(())
}
Enable resumption of interrupted downloads.
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut session = Session::login("user@example.com", "password").await?;
session.refresh().await?;
// Enable resume support
session.set_resume(true);
// Speed up large downloads with parallel workers
session.set_workers(4);
// download_to_file automatically resumes partial downloads
if let Some(node) = session.stat("/Root/LargeVideo.mp4").cloned() {
session.download_to_file(&node, "video.mp4").await?;
}
Ok(())
}
For large uploads that may be interrupted:
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut session = Session::login("user@example.com", "password").await?;
session.refresh().await?;
// Speed up large uploads with parallel workers
session.set_workers(4);
// upload_resumable saves state to .megalib_upload file
// If interrupted, re-running will resume from last chunk
let node = session.upload_resumable("large_file.zip", "/Root").await?;
println!("Uploaded: {}", node.name);
Ok(())
}
Monitor transfer progress:
use megalib::{Session, progress::TransferProgress};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut session = Session::login("user@example.com", "password").await?;
session.refresh().await?;
// Set progress callback
session.watch_status(Box::new(|progress: &TransferProgress| {
println!("{:.1}% - {}", progress.percent(), progress.filename);
true // Return false to cancel
}));
// Upload/download will now report progress
session.upload("file.txt", "/Root").await?;
Ok(())
}
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut session = Session::login("user@example.com", "password").await?;
session.refresh().await?;
let url = session.export("/Root/Project/final.txt").await?;
println!("Public Download Link: {}", url);
Ok(())
}
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut session = Session::login("user@example.com", "password").await?;
session.refresh().await?;
// Export multiple files in one batch (more efficient)
let paths = &["/Root/doc1.pdf", "/Root/doc2.pdf", "/Root/image.png"];
let results = session.export_many(paths).await?;
for (path, url) in results {
println!("{} -> {}", path, url);
}
Ok(())
}
use megalib::Session;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut session = Session::login("user@example.com", "password").await?;
session.refresh().await?;
if let Some(node) = session.stat("/Root/shared_file.txt") {
// Get link if already exported
if let Some(url) = node.get_link(true) {
println!("Existing link: {}", url);
}
// Get just the key (for manual link construction)
if let Some(key) = node.get_key() {
println!("Node key: {}", key);
}
}
Ok(())
}
Share a folder with another MEGA user.
// Share folder with friend@example.com (Read-only)
session.share_folder("FOLDER_HANDLE", "friend@example.com", 0).await?;
Access levels:
0: Read-only
1: Read/Write
2: Full Access
You can interact with public MEGA links without logging in.
use megalib::public::download_public_file;
use std::fs::File;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut file = File::create("shared_file.zip")?;
// Download directly from a public link
download_public_file("https://mega.nz/file/ABC123#key...", &mut file).await?;
println!("Download complete!");
Ok(())
}
use megalib::public::open_folder;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Open a public folder
let folder = open_folder("https://mega.nz/folder/XYZ789#key...").await?;
// List files
for node in folder.list("/", true) {
println!("Found: {} ({} bytes)", node.name, node.size);
// Download a specific file
if node.name == "image.jpg" {
let mut file = std::fs::File::create("image.jpg")?;
folder.download(node, &mut file).await?;
}
}
Ok(())
}
Clone the repository and run the included examples:
# Register
cargo run --example register -- --email test@example.com --password TestPass123 --name "Test User"
# Verify Registration
cargo run --example verify -- "https://mega.nz/#confirm..."
# Change Password
cargo run --example passwd -- --email test@example.com --old OldPass --new NewPass
# Login and list files
cargo run --example ls -- --email test@example.com --password TestPass123 --path /Root/
# Session Caching
cargo run --example cached_session -- --email test@example.com --password TestPass123
# File Operations
cargo run --example mkdir -- --email test@example.com --password TestPass123 /Root/NewFolder
cargo run --example mv -- --email test@example.com --password TestPass123 /Root/file.txt /Root/NewFolder/
cargo run --example rename -- --email test@example.com --password TestPass123 /Root/file.txt "new_name.txt"
cargo run --example rm -- --email test@example.com --password TestPass123 /Root/delete_me.txt
cargo run --example stat -- --email test@example.com --password TestPass123 /Root/file.txt
# Upload (standard)
cargo run --example upload -- --email test@example.com --password TestPass123 local_file.txt /Root/
# Upload with resume support & parallel workers
cargo run --example upload_resume -- --email test@example.com --password TestPass123 large_file.zip /Root/
# Download (standard)
cargo run --example download -- --email test@example.com --password TestPass123 /Root/file.zip ./file.zip
# Download with resume support & parallel workers
cargo run --example download_resume -- --email test@example.com --password TestPass123 /Root/file.zip ./file.zip
# Export public link
cargo run --example export -- --email test@example.com --password TestPass123 /Root/file.txt
# Share a folder
cargo run --example share -- --email test@example.com --password TestPass123 --folder /Root/Documents --recipient friend@example.com --level 0
# Public File Download (no login)
cargo run --example download_public -- "https://mega.nz/file/..."
# Public Folder Browser (no login)
cargo run --example folder -- "https://mega.nz/folder/..."
This project is based on the work of megatools by Ondřej Jirman, which provided the foundational understanding of the MEGA API protocol and served as a reference implementation.
This project is licensed under the GNU General Public License v2.0 (GPLv2) - see the license file for details.
This is an unofficial client library and is not affiliated with, associated with, authorized by, endorsed by, or in any way officially connected with Mega Limited.