<commit_before>//! The base traits that are used for serializing and deserializing rust types.
//!
//! `BerSerialize` implements serialization, and `BerDeserialize` implements deserialization.
//! Both traits depend upon the `Asn1Info` trait being implemented, to provide
//! metadata about the type (like ASN.1 tag and ASN.1 type).
//!
//! For both traits, only the `(de)serialize_value` functions should need overridden
//! to get custom behaviour. If you need to change how tags are handled, you may need
//! to override `_serialize_enc` or `_deserialize_with_tag`.
use std::io;

use ::Asn1Info;
use tag;
use err;
use ber::enc;

/// Provides the methods required to serialize this Rust type into an ASN.1 stream.
///
/// When implementing this for a simple primitive type, implementing `serialize_value`
/// should be all that's required. For more complex, structured types you may need to
/// implement `_serialize_enc` (this is called first by `serialize_enc`).
pub trait BerSerialize: Asn1Info {
  /// Serialize a value into ASN.1 data as DER.
  fn serialize<W: io::Write>(&self, writer: &mut W) -> Result<(), err::EncodeError> {
    self.serialize_enc(enc::DER, writer)
  }

  /// Serialize a value into ASN.1 data using a specific set of encoding rules.
  fn serialize_enc<E: enc::BerEncRules, W: io::Write>
      (&self, e: E, writer: &mut W) -> Result<(), err::EncodeError> {
    debug!("Encoding the type {}", Self::asn1_type());
    if let Some(r) = self._serialize_enc(e, writer) {
      return r;
    }

    let tag = match Self::asn1_tag() {
      Some(tag) => tag,
      None => {
        debug!("Type does not have a tag");
        return self.serialize_value(e, writer);
      },
    };

    try!(tag.write_tag(writer));

    // If this is indefinite length and constructed, write the data directly.
    if E::len_rules() == enc::LenEnc::Indefinite &&
       tag.constructed {
      debug!("Using indefinite length");
      try!(tag::Len::Indef.write_len(writer));
      try!(self.serialize_value(e, writer));
      try!(tag::Len::write_indef_end(writer));
    // Otherwise write to a Vec first, so we can write the length.
    } else {
      debug!("Using definite length encoding");
      let mut bytes: Vec<u8> = Vec::new();
      try!(self.serialize_value(e, &mut bytes));
      try!(tag::Len::write_len(Some(bytes.len() as tag::LenNum).into(), writer));
      try!(writer.write_all(&bytes));
    }

    Ok(())
  }
<commit_msg>Update log message in asn1-cereal<commit_after>//! The base traits that are used for serializing and deserializing rust types.
//!
//! `BerSerialize` implements serialization, and `BerDeserialize` implements deserialization.
//! Both traits depend upon the `Asn1Info` trait being implemented, to provide
//! metadata about the type (like ASN.1 tag and ASN.1 type).
//!
//! For both traits, only the `(de)serialize_value` functions should need overridden
//! to get custom behaviour. If you need to change how tags are handled, you may need
//! to override `_serialize_enc` or `_deserialize_with_tag`.
use std::io;

use ::Asn1Info;
use tag;
use err;
use ber::enc;

/// Provides the methods required to serialize this Rust type into an ASN.1 stream.
///
/// When implementing this for a simple primitive type, implementing `serialize_value`
/// should be all that's required. For more complex, structured types you may need to
/// implement `_serialize_enc` (this is called first by `serialize_enc`).
pub trait BerSerialize: Asn1Info {
  /// Serialize a value into ASN.1 data as DER.
  fn serialize<W: io::Write>(&self, writer: &mut W) -> Result<(), err::EncodeError> {
    self.serialize_enc(enc::DER, writer)
  }

  /// Serialize a value into ASN.1 data using a specific set of encoding rules.
  fn serialize_enc<E: enc::BerEncRules, W: io::Write>
      (&self, e: E, writer: &mut W) -> Result<(), err::EncodeError> {
    debug!("Encoding the type {}", Self::asn1_type());
    if let Some(r) = self._serialize_enc(e, writer) {
      return r;
    }

    let tag = match Self::asn1_tag() {
      Some(tag) => tag,
      None => {
        debug!("Skipping encoding of empty tag");
        return self.serialize_value(e, writer);
      },
    };

    try!(tag.write_tag(writer));

    // If this is indefinite length and constructed, write the data directly.
    if E::len_rules() == enc::LenEnc::Indefinite &&
       tag.constructed {
      debug!("Using indefinite length");
      try!(tag::Len::Indef.write_len(writer));
      try!(self.serialize_value(e, writer));
      try!(tag::Len::write_indef_end(writer));
    // Otherwise write to a Vec first, so we can write the length.
    } else {
      debug!("Using definite length encoding");
      let mut bytes: Vec<u8> = Vec::new();
      try!(self.serialize_value(e, &mut bytes));
      try!(tag::Len::write_len(Some(bytes.len() as tag::LenNum).into(), writer));
      try!(writer.write_all(&bytes));
    }

    Ok(())
  }

{'fraction_non_alphanumeric': 0.13911454102355808, 'fraction_numerical': 0.004670999187652315, 'mean_word_length': 3.4650951949229376, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5546614', 'n_tokens_mistral': 1523, 'n_tokens_neox': 1488, 'n_words': 515}