Skip to main content

nextcloud_users/user/
quota.rs

1use serde::{Deserialize, Serialize};
2
3use crate::wire::{lossy_f64, lossy_i64};
4
5/// User storage quota metrics and capacity constraints.
6///
7/// In Nextcloud, when a quota is set to unlimited, negative integer codes
8/// (typically `-3` or `-2`) are returned for `free` and `total`.
9///
10/// Official documentation:
11/// <https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-api-overview.html#user-metadata>
12#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
13pub struct Quota {
14    /// Space remaining in bytes, or negative code when unlimited.
15    #[serde(default, deserialize_with = "lossy_i64")]
16    pub free: i64,
17    /// Space consumed by user files in bytes.
18    #[serde(default, deserialize_with = "lossy_i64")]
19    pub used: i64,
20    /// Total storage capacity allocated in bytes, or negative code when unlimited.
21    #[serde(default, deserialize_with = "lossy_i64")]
22    pub total: i64,
23    /// Storage usage ratio or percentage (e.g. `0.96` or `96.0`).
24    #[serde(default, deserialize_with = "lossy_f64")]
25    pub relative: f64,
26}
27
28impl Quota {
29    /// Creates a quota descriptor with explicit byte measurements.
30    pub const fn new(free: i64, used: i64, total: i64, relative: f64) -> Self {
31        Self {
32            free,
33            used,
34            total,
35            relative,
36        }
37    }
38
39    /// Available free space in bytes, or a negative status code when unlimited.
40    pub const fn free(&self) -> i64 {
41        self.free
42    }
43
44    /// Bytes consumed by user files.
45    pub const fn used(&self) -> i64 {
46        self.used
47    }
48
49    /// Total storage allocation in bytes, or a negative status code when unlimited.
50    pub const fn total(&self) -> i64 {
51        self.total
52    }
53
54    /// Relative storage utilization metric.
55    pub const fn relative(&self) -> f64 {
56        self.relative
57    }
58
59    /// Whether the user has an unlimited storage allocation.
60    pub const fn is_unlimited(&self) -> bool {
61        self.total < 0
62    }
63
64    /// Available free storage in bytes, or `None` if quota is unlimited.
65    pub fn free_bytes(&self) -> Option<u64> {
66        if self.free >= 0 {
67            Some(self.free as u64)
68        } else {
69            None
70        }
71    }
72
73    /// Total allocated storage capacity in bytes, or `None` if quota is unlimited.
74    pub fn total_bytes(&self) -> Option<u64> {
75        if self.total >= 0 {
76            Some(self.total as u64)
77        } else {
78            None
79        }
80    }
81
82    /// Bytes currently consumed by user files.
83    pub fn used_bytes(&self) -> u64 {
84        self.used.max(0) as u64
85    }
86
87    /// Percentage of storage utilized (0.0 to 100.0).
88    pub fn relative_percentage(&self) -> f64 {
89        if self.relative > 0.0 && self.relative <= 1.0 {
90            self.relative * 100.0
91        } else {
92            self.relative
93        }
94    }
95}