1use std::fmt;
7
8#[cfg(feature = "serde")]
9use serde::{Deserialize, Serialize};
10
11#[derive(Clone, Copy, PartialEq, Eq, Hash)]
35#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
36pub struct ComponentTypeId([u8; 32]);
37
38impl ComponentTypeId {
39 #[inline]
43 pub const fn new(hash: [u8; 32]) -> Self {
44 Self(hash)
45 }
46
47 #[inline]
49 pub const fn as_bytes(&self) -> &[u8; 32] {
50 &self.0
51 }
52
53 #[inline]
55 pub const fn zero() -> Self {
56 Self([0u8; 32])
57 }
58}
59
60impl fmt::Debug for ComponentTypeId {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 write!(f, "ComponentTypeId({})", self)
63 }
64}
65
66impl fmt::Display for ComponentTypeId {
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 for byte in &self.0[..8] {
70 write!(f, "{:02x}", byte)?;
71 }
72 write!(f, "\u{2026}")
73 }
74}
75
76#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
98#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
99pub struct ComponentInstanceId(u64);
100
101impl ComponentInstanceId {
102 #[inline]
106 pub const fn new(id: u64) -> Self {
107 Self(id)
108 }
109
110 #[inline]
112 pub const fn as_u64(&self) -> u64 {
113 self.0
114 }
115}
116
117impl fmt::Debug for ComponentInstanceId {
118 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119 write!(f, "ComponentInstanceId({})", self.0)
120 }
121}
122
123impl fmt::Display for ComponentInstanceId {
124 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125 write!(f, "component-{}", self.0)
126 }
127}
128
129impl From<u64> for ComponentInstanceId {
130 #[inline]
131 fn from(id: u64) -> Self {
132 Self(id)
133 }
134}
135
136pub type ComponentId = ComponentInstanceId;
142
143#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
165#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
166pub struct FlowId(u64);
167
168impl FlowId {
169 #[inline]
173 pub const fn new(id: u64) -> Self {
174 Self(id)
175 }
176
177 #[inline]
179 pub const fn as_u64(&self) -> u64 {
180 self.0
181 }
182}
183
184impl fmt::Debug for FlowId {
185 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
186 write!(f, "FlowId({})", self.0)
187 }
188}
189
190impl fmt::Display for FlowId {
191 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
192 write!(f, "flow-{}", self.0)
193 }
194}
195
196impl From<u64> for FlowId {
197 #[inline]
198 fn from(id: u64) -> Self {
199 Self(id)
200 }
201}
202
203#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
224#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
225pub struct StreamId(u64);
226
227impl StreamId {
228 #[inline]
232 pub const fn new(id: u64) -> Self {
233 Self(id)
234 }
235
236 #[inline]
238 pub const fn as_u64(&self) -> u64 {
239 self.0
240 }
241}
242
243impl fmt::Debug for StreamId {
244 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
245 write!(f, "StreamId({})", self.0)
246 }
247}
248
249impl fmt::Display for StreamId {
250 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
251 write!(f, "stream-{}", self.0)
252 }
253}
254
255impl From<u64> for StreamId {
256 #[inline]
257 fn from(id: u64) -> Self {
258 Self(id)
259 }
260}
261
262#[derive(Clone, Copy, PartialEq, Eq, Hash)]
287#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
288pub struct ResourceId {
289 index: u32,
290 generation: u32,
291}
292
293impl ResourceId {
294 #[inline]
298 pub const fn new(index: u32, generation: u32) -> Self {
299 Self { index, generation }
300 }
301
302 #[inline]
304 pub const fn index(&self) -> u32 {
305 self.index
306 }
307
308 #[inline]
310 pub const fn generation(&self) -> u32 {
311 self.generation
312 }
313
314 #[inline]
318 pub const fn next_generation(&self) -> Self {
319 Self {
320 index: self.index,
321 generation: self.generation.wrapping_add(1),
322 }
323 }
324}
325
326impl fmt::Debug for ResourceId {
327 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
328 write!(f, "ResourceId({}, gen={})", self.index, self.generation)
329 }
330}
331
332impl fmt::Display for ResourceId {
333 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
334 write!(f, "resource-{}:g{}", self.index, self.generation)
335 }
336}
337
338#[derive(Clone, Copy, PartialEq, Eq, Hash)]
359#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
360pub struct BufferHandle(ResourceId);
361
362impl BufferHandle {
363 #[inline]
367 pub const fn new(resource_id: ResourceId) -> Self {
368 Self(resource_id)
369 }
370
371 #[inline]
373 pub const fn resource_id(&self) -> ResourceId {
374 self.0
375 }
376}
377
378impl fmt::Debug for BufferHandle {
379 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
380 write!(f, "BufferHandle({})", self.0)
381 }
382}
383
384impl fmt::Display for BufferHandle {
385 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
386 write!(f, "buffer-{}:g{}", self.0.index(), self.0.generation())
387 }
388}
389
390impl From<ResourceId> for BufferHandle {
391 #[inline]
392 fn from(id: ResourceId) -> Self {
393 Self(id)
394 }
395}
396
397#[derive(Clone, Copy, PartialEq, Eq, Hash)]
419#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
420pub struct TraceId([u8; 16]);
421
422impl TraceId {
423 #[inline]
427 pub const fn new(bytes: [u8; 16]) -> Self {
428 Self(bytes)
429 }
430
431 #[inline]
433 pub const fn as_bytes(&self) -> &[u8; 16] {
434 &self.0
435 }
436
437 #[inline]
439 pub fn is_valid(&self) -> bool {
440 self.0 != [0u8; 16]
441 }
442
443 #[inline]
445 pub const fn invalid() -> Self {
446 Self([0u8; 16])
447 }
448}
449
450impl fmt::Debug for TraceId {
451 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
452 write!(f, "TraceId({})", self)
453 }
454}
455
456impl fmt::Display for TraceId {
457 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
458 for byte in &self.0 {
459 write!(f, "{:02x}", byte)?;
460 }
461 Ok(())
462 }
463}
464
465#[derive(Clone, Copy, PartialEq, Eq, Hash)]
486#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
487pub struct SpanId([u8; 8]);
488
489impl SpanId {
490 #[inline]
494 pub const fn new(bytes: [u8; 8]) -> Self {
495 Self(bytes)
496 }
497
498 #[inline]
500 pub const fn as_bytes(&self) -> &[u8; 8] {
501 &self.0
502 }
503
504 #[inline]
506 pub fn is_valid(&self) -> bool {
507 self.0 != [0u8; 8]
508 }
509
510 #[inline]
512 pub const fn invalid() -> Self {
513 Self([0u8; 8])
514 }
515}
516
517impl fmt::Debug for SpanId {
518 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
519 write!(f, "SpanId({})", self)
520 }
521}
522
523impl fmt::Display for SpanId {
524 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
525 for byte in &self.0 {
526 write!(f, "{:02x}", byte)?;
527 }
528 Ok(())
529 }
530}
531
532#[cfg(test)]
537mod tests {
538 use super::*;
539
540 #[test]
543 fn test_component_type_id_new_and_bytes() {
544 let hash = [0xab; 32];
545 let id = ComponentTypeId::new(hash);
546 assert_eq!(id.as_bytes(), &[0xab; 32]);
547 }
548
549 #[test]
550 fn test_component_type_id_zero() {
551 let id = ComponentTypeId::zero();
552 assert_eq!(id.as_bytes(), &[0u8; 32]);
553 }
554
555 #[test]
556 fn test_component_type_id_equality() {
557 let a = ComponentTypeId::new([1; 32]);
558 let b = ComponentTypeId::new([1; 32]);
559 let c = ComponentTypeId::new([2; 32]);
560 assert_eq!(a, b);
561 assert_ne!(a, c);
562 }
563
564 #[test]
565 fn test_component_type_id_display_truncated() {
566 let id = ComponentTypeId::new([0xab; 32]);
567 let display = format!("{}", id);
568 assert!(display.starts_with("abababab"));
569 assert!(display.ends_with('\u{2026}'));
570 }
571
572 #[test]
573 fn test_component_type_id_hash_consistency() {
574 use std::collections::HashSet;
575 let mut set = HashSet::new();
576 let id = ComponentTypeId::new([0xcd; 32]);
577 set.insert(id);
578 assert!(set.contains(&ComponentTypeId::new([0xcd; 32])));
579 }
580
581 #[test]
584 fn test_component_instance_id_new_and_value() {
585 let id = ComponentInstanceId::new(42);
586 assert_eq!(id.as_u64(), 42);
587 }
588
589 #[test]
590 fn test_component_instance_id_display() {
591 let id = ComponentInstanceId::new(42);
592 assert_eq!(format!("{}", id), "component-42");
593 }
594
595 #[test]
596 fn test_component_instance_id_ordering() {
597 let a = ComponentInstanceId::new(1);
598 let b = ComponentInstanceId::new(2);
599 assert!(a < b);
600 }
601
602 #[test]
603 fn test_component_instance_id_from_u64() {
604 let id: ComponentInstanceId = 99u64.into();
605 assert_eq!(id.as_u64(), 99);
606 }
607
608 #[test]
609 fn test_component_id_alias() {
610 let id: ComponentId = ComponentInstanceId::new(10);
611 assert_eq!(id.as_u64(), 10);
612 }
613
614 #[test]
617 fn test_flow_id_new_and_value() {
618 let id = FlowId::new(7);
619 assert_eq!(id.as_u64(), 7);
620 }
621
622 #[test]
623 fn test_flow_id_display() {
624 let id = FlowId::new(7);
625 assert_eq!(format!("{}", id), "flow-7");
626 }
627
628 #[test]
629 fn test_flow_id_ordering() {
630 let a = FlowId::new(1);
631 let b = FlowId::new(2);
632 assert!(a < b);
633 }
634
635 #[test]
636 fn test_flow_id_from_u64() {
637 let id: FlowId = 55u64.into();
638 assert_eq!(id.as_u64(), 55);
639 }
640
641 #[test]
644 fn test_stream_id_new_and_value() {
645 let id = StreamId::new(3);
646 assert_eq!(id.as_u64(), 3);
647 }
648
649 #[test]
650 fn test_stream_id_display() {
651 let id = StreamId::new(3);
652 assert_eq!(format!("{}", id), "stream-3");
653 }
654
655 #[test]
658 fn test_resource_id_new_and_fields() {
659 let id = ResourceId::new(10, 1);
660 assert_eq!(id.index(), 10);
661 assert_eq!(id.generation(), 1);
662 }
663
664 #[test]
665 fn test_resource_id_display() {
666 let id = ResourceId::new(10, 1);
667 assert_eq!(format!("{}", id), "resource-10:g1");
668 }
669
670 #[test]
671 fn test_resource_id_next_generation() {
672 let id = ResourceId::new(5, 0);
673 let next = id.next_generation();
674 assert_eq!(next.index(), 5);
675 assert_eq!(next.generation(), 1);
676 }
677
678 #[test]
679 fn test_resource_id_generation_wraps() {
680 let id = ResourceId::new(0, u32::MAX);
681 let next = id.next_generation();
682 assert_eq!(next.generation(), 0);
683 }
684
685 #[test]
686 fn test_resource_id_different_generations_not_equal() {
687 let a = ResourceId::new(5, 0);
688 let b = ResourceId::new(5, 1);
689 assert_ne!(a, b);
690 }
691
692 #[test]
695 fn test_buffer_handle_new_and_resource_id() {
696 let rid = ResourceId::new(5, 0);
697 let handle = BufferHandle::new(rid);
698 assert_eq!(handle.resource_id(), rid);
699 }
700
701 #[test]
702 fn test_buffer_handle_display() {
703 let handle = BufferHandle::new(ResourceId::new(5, 2));
704 assert_eq!(format!("{}", handle), "buffer-5:g2");
705 }
706
707 #[test]
708 fn test_buffer_handle_from_resource_id() {
709 let rid = ResourceId::new(3, 1);
710 let handle: BufferHandle = rid.into();
711 assert_eq!(handle.resource_id(), rid);
712 }
713
714 #[test]
717 fn test_trace_id_valid() {
718 let id = TraceId::new([1; 16]);
719 assert!(id.is_valid());
720 }
721
722 #[test]
723 fn test_trace_id_invalid_zero() {
724 let id = TraceId::invalid();
725 assert!(!id.is_valid());
726 }
727
728 #[test]
729 fn test_trace_id_display_length() {
730 let id = TraceId::new([0xab; 16]);
731 assert_eq!(id.to_string().len(), 32); }
733
734 #[test]
735 fn test_trace_id_display_value() {
736 let id = TraceId::new([
737 0x4b, 0xf9, 0x2f, 0x35, 0x77, 0xb3, 0x4d, 0xa6, 0xa3, 0xce, 0x92, 0x9d, 0x0e, 0x0e,
738 0x47, 0x36,
739 ]);
740 assert_eq!(id.to_string(), "4bf92f3577b34da6a3ce929d0e0e4736");
741 }
742
743 #[test]
746 fn test_span_id_valid() {
747 let id = SpanId::new([1; 8]);
748 assert!(id.is_valid());
749 }
750
751 #[test]
752 fn test_span_id_invalid_zero() {
753 let id = SpanId::invalid();
754 assert!(!id.is_valid());
755 }
756
757 #[test]
758 fn test_span_id_display_length() {
759 let id = SpanId::new([0xab; 8]);
760 assert_eq!(id.to_string().len(), 16); }
762}