async-dns icon indicating copy to clipboard operation
async-dns copied to clipboard

Split `Serialize` trait and make it public

Open al8n opened this issue 11 months ago • 1 comments

Hi, thanks for the amazing project!

I am using dns-protocol separately for implementing an mDNS, and need to pre-allocate enough space to hold a SRV resource record data. This PR exports the Serialize trait so that users can access the serialize_len and serialize methods.

#[derive(Debug, PartialEq, Eq, Hash, Clone)]
#[allow(clippy::upper_case_acronyms)]
pub struct SRV {
  data: Arc<[u8]>,
  target: SmolStr,
}

impl SRV {
  const PRIORITY_OFFSET: usize = 0;
  const WEIGHT_OFFSET: usize = 2;
  const PORT_OFFSET: usize = 4;
  const TARGET_OFFSET: usize = 6;

  const PRIORITY_END: usize = 2;
  const WEIGHT_END: usize = 4;
  const PORT_END: usize = 6;

  const PRIORITY_RANGE: Range<usize> = Self::PORT_OFFSET..Self::PRIORITY_END;
  const WEIGHT_RANGE: Range<usize> = Self::WEIGHT_OFFSET..Self::WEIGHT_END;
  const PORT_RANGE: Range<usize> = Self::PORT_OFFSET..Self::PORT_END;
  const TARGET_RANGE: RangeFrom<usize> = Self::TARGET_OFFSET..;

  /// Creates a new SRV record data.
  #[inline]
  pub fn new(priority: u16, weight: u16, port: u16, target: SmolStr) -> Self {
    let label = Label::from(target.as_str());
    let len = label.serialized_len();
    let mut buf = vec![0; Self::TARGET_OFFSET + len];
    buf[Self::PRIORITY_RANGE].copy_from_slice(priority.to_ne_bytes().as_ref());
    buf[Self::WEIGHT_RANGE].copy_from_slice(weight.to_ne_bytes().as_ref());
    buf[Self::PORT_RANGE].copy_from_slice(port.to_ne_bytes().as_ref());
    
    label.serialize(&mut buf[Self::TARGET_RANGE]);
    Self {
      data: Arc::from(buf),
      target,
    }
  }

  /// Returns the bytes format of the SRV record data.
  /// 
  /// The result is the encoded bytes of the SRV record data.
  /// 
  /// This operation is O(1).
  #[inline]
  pub fn data(&self) -> &[u8] {
    &self.data
  }
  
  /// Returns a resource record from the `SRV`.
  #[inline]
  pub fn to_resource_record<'a>(&'a self, name: &'a str, ty: ResourceType, class: u16, ttl: u32) -> ResourceRecord<'a> {
    ResourceRecord::new(name, ty, class, ttl, self.data())
  }
}

al8n avatar Jan 28 '25 04:01 al8n

Hi @notgull, sorry for ping you here. Do you have any idea for this?

al8n avatar Mar 12 '25 02:03 al8n