fxprof_processed_profile/
category.rs

1use serde::ser::{Serialize, SerializeMap, Serializer};
2
3use super::category_color::CategoryColor;
4
5/// A profiling category, can be set on stack frames and markers as part of a [`CategoryPairHandle`].
6///
7/// Categories can be created with [`Profile::add_category`](crate::Profile::add_category).
8#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
9pub struct CategoryHandle(pub(crate) u16);
10
11impl CategoryHandle {
12    /// The "Other" category. All profiles have this category.
13    pub const OTHER: Self = CategoryHandle(0);
14}
15
16impl Serialize for CategoryHandle {
17    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
18        self.0.serialize(serializer)
19    }
20}
21
22/// A profiling subcategory, can be set on stack frames and markers as part of a [`CategoryPairHandle`].
23///
24/// Subategories can be created with [`Profile::add_subcategory`](crate::Profile::add_subcategory).
25#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
26pub struct SubcategoryIndex(pub u16);
27
28impl SubcategoryIndex {
29    /// The "Other" subcategory. All categories have this subcategory as their first subcategory.
30    pub const OTHER: Self = SubcategoryIndex(0);
31}
32
33/// A profiling category pair, consisting of a category and an optional subcategory. Can be set on stack frames and markers.
34///
35/// Category pairs can be created with [`Profile::add_subcategory`](crate::Profile::add_subcategory)
36/// and from a [`CategoryHandle`].
37#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
38pub struct CategoryPairHandle(pub(crate) CategoryHandle, pub(crate) SubcategoryIndex);
39
40impl From<CategoryHandle> for CategoryPairHandle {
41    fn from(category: CategoryHandle) -> Self {
42        CategoryPairHandle(category, SubcategoryIndex::OTHER)
43    }
44}
45
46/// The information about a category.
47#[derive(Debug)]
48pub struct InternalCategory {
49    name: String,
50    color: CategoryColor,
51    subcategories: Vec<String>,
52}
53
54impl InternalCategory {
55    pub fn new(name: String, color: CategoryColor) -> Self {
56        let subcategories = vec!["Other".to_string()];
57        Self {
58            name,
59            color,
60            subcategories,
61        }
62    }
63
64    /// Add a subcategory to this category.
65    pub fn add_subcategory(&mut self, subcategory_name: String) -> SubcategoryIndex {
66        let subcategory_index = SubcategoryIndex(u16::try_from(self.subcategories.len()).unwrap());
67        self.subcategories.push(subcategory_name);
68        subcategory_index
69    }
70}
71
72impl Serialize for InternalCategory {
73    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
74        let mut map = serializer.serialize_map(None)?;
75        map.serialize_entry("name", &self.name)?;
76        map.serialize_entry("color", &self.color)?;
77        map.serialize_entry("subcategories", &self.subcategories)?;
78        map.end()
79    }
80}
81
82impl Serialize for SubcategoryIndex {
83    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
84        self.0.serialize(serializer)
85    }
86}