Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/zerovec-derive/src/   (Firefox Browser Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 4 kB image not shown  

Quelle  ule.rs

  Sprache: Rust
 

// This file is part of ICU4X. For terms of use, please see the file
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).

use proc_macro2::TokenStream as TokenStream2;
use quote::quote;

use crate::utils::{self, FieldInfo};
use syn::spanned::Spanned;
use syn::{Data, DeriveInput, Error};

pub fn derive_impl(input: &DeriveInput) -> TokenStream2 {
    if !utils::ReprInfo::compute(&input.attrs).cpacked_or_transparent() {
        return Error::new(
            input.span(),
            "derive(ULE) must be applied to a #[repr(C, packed)] or #[repr(transparent)] type",
        )
        .to_compile_error();
    }
    if input.generics.type_params().next().is_some()
        || input.generics.lifetimes().next().is_some()
        || input.generics.const_params().next().is_some()
    {
        return Error::new(
            input.generics.span(),
            "derive(ULE) must be applied to a struct without any generics",
        )
        .to_compile_error();
    }
    let struc = if let Data::Struct(ref s) = input.data {
        if s.fields.iter().next().is_none() {
            return Error::new(
                input.span(),
                "derive(ULE) must be applied to a non-empty struct",
            )
            .to_compile_error();
        }
        s
    } else {
        return Error::new(input.span(), "derive(ULE) must be applied to a struct")
            .to_compile_error();
    };

    let fields = FieldInfo::make_list(struc.fields.iter());
    let (validators, remaining_offset) = generate_ule_validators(&fields);

    let name = &input.ident;

    // Safety (based on the safety checklist on the ULE trait):
    //  1. #name does not include any uninitialized or padding bytes.
    //     (achieved by enforcing #[repr(transparent)] or #[repr(packed)] on a struct of only ULE types)
    //  2. #name is aligned to 1 byte.
    //     (achieved by enforcing #[repr(transparent)] or #[repr(packed)] on a struct of only ULE types)
    //  3. The impl of validate_byte_slice() returns an error if any byte is not valid.
    //  4. The impl of validate_byte_slice() returns an error if there are extra bytes.
    //  5. The other ULE methods use the default impl.
    //  6. [This impl does not enforce the non-safety equality constraint, it is up to the user to do so, ideally via a custom derive]
    quote! {
        unsafe impl zerovec::ule::ULE for #name {
            #[inline]
            fn validate_byte_slice(bytes: &[u8]) -> Result<(), zerovec::ZeroVecError> {
                const SIZE: usize = ::core::mem::size_of::<#name>();
                #[allow(clippy::modulo_one)]
                if bytes.len() % SIZE != 0 {
                    return Err(zerovec::ZeroVecError::length::<Self>(bytes.len()));
                }
                // Validate the bytes
                #[allow(clippy::indexing_slicing)] // We're slicing a chunk of known size
                for chunk in bytes.chunks_exact(SIZE) {
                    #validators
                    debug_assert_eq!(#remaining_offset, SIZE);
                }
                Ok(())
            }
        }
    }
}

/// Given an slice over ULE struct fields, returns code validating that a slice variable `bytes` contains valid instances of those ULE types
/// in order, plus the byte offset of any remaining unvalidated bytes. ULE types should not have any remaining bytes, but VarULE types will since
/// the last field is the unsized one.
pub(cratefn generate_ule_validators(
    fields: &[FieldInfo],
    // (validators, remaining_offset)
) -> (TokenStream2, syn::Ident) {
    utils::generate_per_field_offsets(fields, false, |field, prev_offset_ident, size_ident| {
        let ty = &field.field.ty;
        quote! {
            #[allow(clippy::indexing_slicing)] // generate_per_field_offsets produces valid indices
            <#ty as zerovec::ule::ULE>::validate_byte_slice(&bytes[#prev_offset_ident .. #prev_offset_ident + #size_ident])?;
        }
    })
}

/// Make corresponding ULE fields for each field
pub(cratefn make_ule_fields(fields: &[FieldInfo]) -> Vec<TokenStream2> {
    fields
        .iter()
        .map(|f| {
            let ty = &f.field.ty;
            let ty = quote!(<#ty as zerovec::ule::AsULE>::ULE);
            let setter = f.setter();
            let vis = &f.field.vis;
            quote!(#vis #setter #ty)
        })
        .collect::<Vec<_>>()
}

Messung V0.5 in Prozent
C=75 H=90 G=82

¤ Dauer der Verarbeitung: 0.17 Sekunden  (vorverarbeitet am  2026-06-19) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.