How to programmatically get the number of fields of a struct?












15















I have a custom struct like the following:



struct MyStruct {
first_field: i32,
second_field: String,
third_field: u16,
}


Is it possible to get the number of struct fields programmatically (like, for example, via a method call field_count()):



let my_struct = MyStruct::new(10, "second_field", 4);
let field_count = my_struct.field_count(); // Expecting to get 3


For this struct:



struct MyStruct2 {
first_field: i32,
}


... the following call should return 1:



let my_struct_2 = MyStruct2::new(7);
let field_count = my_struct2.field_count(); // Expecting to get count 1


Is there any API like field_count() or is it only possible to get that via macros?



If this is achievable with macros, how should it be implemented?










share|improve this question




















  • 1





    What is the purpose of doing this? The language is statically typed, so the function would be constant, that is you'd always get the same answer and there is no useful decision to be made based on that.

    – Jan Hudec
    9 hours ago






  • 1





    @Jan Hudec, Let's say you have written statically the count on some different blocks of the program and at some time you change the struct and added a new field. Then, I do not want to edit the count on everywhere else which can be automaticlly handled

    – Akiner Alkan
    8 hours ago






  • 1





    That still does not say what is a use for this information at all in the first place. Any code that depends on the number of fields will depend on it at compile-time, and will probably depend on the types and names of the fields too. When the fields change, it will either fail to compile, or it is generated, in which case the generator needs the information-and custom derive is the right tool for that.

    – Jan Hudec
    7 hours ago
















15















I have a custom struct like the following:



struct MyStruct {
first_field: i32,
second_field: String,
third_field: u16,
}


Is it possible to get the number of struct fields programmatically (like, for example, via a method call field_count()):



let my_struct = MyStruct::new(10, "second_field", 4);
let field_count = my_struct.field_count(); // Expecting to get 3


For this struct:



struct MyStruct2 {
first_field: i32,
}


... the following call should return 1:



let my_struct_2 = MyStruct2::new(7);
let field_count = my_struct2.field_count(); // Expecting to get count 1


Is there any API like field_count() or is it only possible to get that via macros?



If this is achievable with macros, how should it be implemented?










share|improve this question




















  • 1





    What is the purpose of doing this? The language is statically typed, so the function would be constant, that is you'd always get the same answer and there is no useful decision to be made based on that.

    – Jan Hudec
    9 hours ago






  • 1





    @Jan Hudec, Let's say you have written statically the count on some different blocks of the program and at some time you change the struct and added a new field. Then, I do not want to edit the count on everywhere else which can be automaticlly handled

    – Akiner Alkan
    8 hours ago






  • 1





    That still does not say what is a use for this information at all in the first place. Any code that depends on the number of fields will depend on it at compile-time, and will probably depend on the types and names of the fields too. When the fields change, it will either fail to compile, or it is generated, in which case the generator needs the information-and custom derive is the right tool for that.

    – Jan Hudec
    7 hours ago














15












15








15


3






I have a custom struct like the following:



struct MyStruct {
first_field: i32,
second_field: String,
third_field: u16,
}


Is it possible to get the number of struct fields programmatically (like, for example, via a method call field_count()):



let my_struct = MyStruct::new(10, "second_field", 4);
let field_count = my_struct.field_count(); // Expecting to get 3


For this struct:



struct MyStruct2 {
first_field: i32,
}


... the following call should return 1:



let my_struct_2 = MyStruct2::new(7);
let field_count = my_struct2.field_count(); // Expecting to get count 1


Is there any API like field_count() or is it only possible to get that via macros?



If this is achievable with macros, how should it be implemented?










share|improve this question
















I have a custom struct like the following:



struct MyStruct {
first_field: i32,
second_field: String,
third_field: u16,
}


Is it possible to get the number of struct fields programmatically (like, for example, via a method call field_count()):



let my_struct = MyStruct::new(10, "second_field", 4);
let field_count = my_struct.field_count(); // Expecting to get 3


For this struct:



struct MyStruct2 {
first_field: i32,
}


... the following call should return 1:



let my_struct_2 = MyStruct2::new(7);
let field_count = my_struct2.field_count(); // Expecting to get count 1


Is there any API like field_count() or is it only possible to get that via macros?



If this is achievable with macros, how should it be implemented?







struct rust rust-macros rust-proc-macros






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 3 hours ago









Shepmaster

149k13290428




149k13290428










asked 9 hours ago









Akiner AlkanAkiner Alkan

784222




784222








  • 1





    What is the purpose of doing this? The language is statically typed, so the function would be constant, that is you'd always get the same answer and there is no useful decision to be made based on that.

    – Jan Hudec
    9 hours ago






  • 1





    @Jan Hudec, Let's say you have written statically the count on some different blocks of the program and at some time you change the struct and added a new field. Then, I do not want to edit the count on everywhere else which can be automaticlly handled

    – Akiner Alkan
    8 hours ago






  • 1





    That still does not say what is a use for this information at all in the first place. Any code that depends on the number of fields will depend on it at compile-time, and will probably depend on the types and names of the fields too. When the fields change, it will either fail to compile, or it is generated, in which case the generator needs the information-and custom derive is the right tool for that.

    – Jan Hudec
    7 hours ago














  • 1





    What is the purpose of doing this? The language is statically typed, so the function would be constant, that is you'd always get the same answer and there is no useful decision to be made based on that.

    – Jan Hudec
    9 hours ago






  • 1





    @Jan Hudec, Let's say you have written statically the count on some different blocks of the program and at some time you change the struct and added a new field. Then, I do not want to edit the count on everywhere else which can be automaticlly handled

    – Akiner Alkan
    8 hours ago






  • 1





    That still does not say what is a use for this information at all in the first place. Any code that depends on the number of fields will depend on it at compile-time, and will probably depend on the types and names of the fields too. When the fields change, it will either fail to compile, or it is generated, in which case the generator needs the information-and custom derive is the right tool for that.

    – Jan Hudec
    7 hours ago








1




1





What is the purpose of doing this? The language is statically typed, so the function would be constant, that is you'd always get the same answer and there is no useful decision to be made based on that.

– Jan Hudec
9 hours ago





What is the purpose of doing this? The language is statically typed, so the function would be constant, that is you'd always get the same answer and there is no useful decision to be made based on that.

– Jan Hudec
9 hours ago




1




1





@Jan Hudec, Let's say you have written statically the count on some different blocks of the program and at some time you change the struct and added a new field. Then, I do not want to edit the count on everywhere else which can be automaticlly handled

– Akiner Alkan
8 hours ago





@Jan Hudec, Let's say you have written statically the count on some different blocks of the program and at some time you change the struct and added a new field. Then, I do not want to edit the count on everywhere else which can be automaticlly handled

– Akiner Alkan
8 hours ago




1




1





That still does not say what is a use for this information at all in the first place. Any code that depends on the number of fields will depend on it at compile-time, and will probably depend on the types and names of the fields too. When the fields change, it will either fail to compile, or it is generated, in which case the generator needs the information-and custom derive is the right tool for that.

– Jan Hudec
7 hours ago





That still does not say what is a use for this information at all in the first place. Any code that depends on the number of fields will depend on it at compile-time, and will probably depend on the types and names of the fields too. When the fields change, it will either fail to compile, or it is generated, in which case the generator needs the information-and custom derive is the right tool for that.

– Jan Hudec
7 hours ago












2 Answers
2






active

oldest

votes


















18















Are there any possible API like field_count() or is it only possible to get that via macros?




There is no such built-in API that would allow you to get this information at runtime. Rust does not have runtime reflection (see this question for more information). But it is indeed possible via proc-macros!



Note: proc-macros are different from "macro by example" (which is declared via macro_rules!). The latter is not as powerful as proc-macros.




If this is achievable with macros, how should it be implemented?




(This is not an introduction into proc-macros; if the topic is completely new to you, first read an introduction elsewhere.)



In the proc-macro (for example a custom derive), you would somehow need to get the struct definition as TokenStream. The de-facto solution to use a TokenStream with Rust syntax is to parse it via syn:



#[proc_macro_derive(FieldCount)]
pub fn derive_field_count(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as ItemStruct);

// ...
}


The type of input is ItemStruct. As you can see, it has the field fields of the type Fields. On that field you can call iter() to get an iterator over all fields of the struct, on which in turn you could call count():



let field_count = input.fields.iter().count();


Now you have what you want.



Maybe you want to add this field_count() method to your type. You can do that via the custom derive (by using the quote crate here):



let name = &input.ident;

let output = quote! {
impl #name {
pub fn field_count() -> usize {
#field_count
}
}
};

// Return output tokenstream
TokenStream::from(output)


Then, in your application, you can write:



#[derive(FieldCount)]
struct MyStruct {
first_field: i32,
second_field: String,
third_field: u16,
}

MyStruct::field_count(); // returns 3





share|improve this answer





















  • 1





    Instead of a derive, you can also make it a custom attribute, see the reference for details

    – hellow
    8 hours ago













  • Shouldn't the last line of the macro read TokenStream::from (output) instead of TokenStream::from (expanded)?

    – Jmb
    7 hours ago











  • Note: run-time reflection is not necessary, run-time introspection or even compile-time introspection would be sufficient. And indeed, it turns out that using a derive/attribute/proc-macro is compile-time introspection.

    – Matthieu M.
    7 hours ago











  • @Jmb if you are certain, you can edit the answer next time yourself ;)

    – hellow
    7 hours ago








  • 1





    @Jmb Good catch. Sadly, I didn't have a compiler at hand when I wrote the answer. So I replaced cargo check with "looking at the code", which is always a bad idea...

    – Lukas Kalbertodt
    5 hours ago



















5














It's possible when the struct itself is generated by the macros - in this case you can just count tokens passed into macros, as shown here. That's what I've come up with:



macro_rules! gen {
($name:ident {$($field:ident : $t:ty),+}) => {
struct $name { $($field: $t),+ }
impl $name {
fn field_count(&self) -> usize {
gen!(@count $($field),+)
}
}
};
(@count $t1:tt, $($t:tt),+) => { 1 + gen!(@count $($t),+) };
(@count $t:tt) => { 1 };
}


Playground (with some test cases)



The downside for this approach (one - there could be more) is that it's not trivial to add an attribute to this function - for example, to #[derive(...)] something on it. Another approach would be to write the custom derive macros, but this is something that I can't speak about for now.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54177438%2fhow-to-programmatically-get-the-number-of-fields-of-a-struct%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    18















    Are there any possible API like field_count() or is it only possible to get that via macros?




    There is no such built-in API that would allow you to get this information at runtime. Rust does not have runtime reflection (see this question for more information). But it is indeed possible via proc-macros!



    Note: proc-macros are different from "macro by example" (which is declared via macro_rules!). The latter is not as powerful as proc-macros.




    If this is achievable with macros, how should it be implemented?




    (This is not an introduction into proc-macros; if the topic is completely new to you, first read an introduction elsewhere.)



    In the proc-macro (for example a custom derive), you would somehow need to get the struct definition as TokenStream. The de-facto solution to use a TokenStream with Rust syntax is to parse it via syn:



    #[proc_macro_derive(FieldCount)]
    pub fn derive_field_count(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as ItemStruct);

    // ...
    }


    The type of input is ItemStruct. As you can see, it has the field fields of the type Fields. On that field you can call iter() to get an iterator over all fields of the struct, on which in turn you could call count():



    let field_count = input.fields.iter().count();


    Now you have what you want.



    Maybe you want to add this field_count() method to your type. You can do that via the custom derive (by using the quote crate here):



    let name = &input.ident;

    let output = quote! {
    impl #name {
    pub fn field_count() -> usize {
    #field_count
    }
    }
    };

    // Return output tokenstream
    TokenStream::from(output)


    Then, in your application, you can write:



    #[derive(FieldCount)]
    struct MyStruct {
    first_field: i32,
    second_field: String,
    third_field: u16,
    }

    MyStruct::field_count(); // returns 3





    share|improve this answer





















    • 1





      Instead of a derive, you can also make it a custom attribute, see the reference for details

      – hellow
      8 hours ago













    • Shouldn't the last line of the macro read TokenStream::from (output) instead of TokenStream::from (expanded)?

      – Jmb
      7 hours ago











    • Note: run-time reflection is not necessary, run-time introspection or even compile-time introspection would be sufficient. And indeed, it turns out that using a derive/attribute/proc-macro is compile-time introspection.

      – Matthieu M.
      7 hours ago











    • @Jmb if you are certain, you can edit the answer next time yourself ;)

      – hellow
      7 hours ago








    • 1





      @Jmb Good catch. Sadly, I didn't have a compiler at hand when I wrote the answer. So I replaced cargo check with "looking at the code", which is always a bad idea...

      – Lukas Kalbertodt
      5 hours ago
















    18















    Are there any possible API like field_count() or is it only possible to get that via macros?




    There is no such built-in API that would allow you to get this information at runtime. Rust does not have runtime reflection (see this question for more information). But it is indeed possible via proc-macros!



    Note: proc-macros are different from "macro by example" (which is declared via macro_rules!). The latter is not as powerful as proc-macros.




    If this is achievable with macros, how should it be implemented?




    (This is not an introduction into proc-macros; if the topic is completely new to you, first read an introduction elsewhere.)



    In the proc-macro (for example a custom derive), you would somehow need to get the struct definition as TokenStream. The de-facto solution to use a TokenStream with Rust syntax is to parse it via syn:



    #[proc_macro_derive(FieldCount)]
    pub fn derive_field_count(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as ItemStruct);

    // ...
    }


    The type of input is ItemStruct. As you can see, it has the field fields of the type Fields. On that field you can call iter() to get an iterator over all fields of the struct, on which in turn you could call count():



    let field_count = input.fields.iter().count();


    Now you have what you want.



    Maybe you want to add this field_count() method to your type. You can do that via the custom derive (by using the quote crate here):



    let name = &input.ident;

    let output = quote! {
    impl #name {
    pub fn field_count() -> usize {
    #field_count
    }
    }
    };

    // Return output tokenstream
    TokenStream::from(output)


    Then, in your application, you can write:



    #[derive(FieldCount)]
    struct MyStruct {
    first_field: i32,
    second_field: String,
    third_field: u16,
    }

    MyStruct::field_count(); // returns 3





    share|improve this answer





















    • 1





      Instead of a derive, you can also make it a custom attribute, see the reference for details

      – hellow
      8 hours ago













    • Shouldn't the last line of the macro read TokenStream::from (output) instead of TokenStream::from (expanded)?

      – Jmb
      7 hours ago











    • Note: run-time reflection is not necessary, run-time introspection or even compile-time introspection would be sufficient. And indeed, it turns out that using a derive/attribute/proc-macro is compile-time introspection.

      – Matthieu M.
      7 hours ago











    • @Jmb if you are certain, you can edit the answer next time yourself ;)

      – hellow
      7 hours ago








    • 1





      @Jmb Good catch. Sadly, I didn't have a compiler at hand when I wrote the answer. So I replaced cargo check with "looking at the code", which is always a bad idea...

      – Lukas Kalbertodt
      5 hours ago














    18












    18








    18








    Are there any possible API like field_count() or is it only possible to get that via macros?




    There is no such built-in API that would allow you to get this information at runtime. Rust does not have runtime reflection (see this question for more information). But it is indeed possible via proc-macros!



    Note: proc-macros are different from "macro by example" (which is declared via macro_rules!). The latter is not as powerful as proc-macros.




    If this is achievable with macros, how should it be implemented?




    (This is not an introduction into proc-macros; if the topic is completely new to you, first read an introduction elsewhere.)



    In the proc-macro (for example a custom derive), you would somehow need to get the struct definition as TokenStream. The de-facto solution to use a TokenStream with Rust syntax is to parse it via syn:



    #[proc_macro_derive(FieldCount)]
    pub fn derive_field_count(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as ItemStruct);

    // ...
    }


    The type of input is ItemStruct. As you can see, it has the field fields of the type Fields. On that field you can call iter() to get an iterator over all fields of the struct, on which in turn you could call count():



    let field_count = input.fields.iter().count();


    Now you have what you want.



    Maybe you want to add this field_count() method to your type. You can do that via the custom derive (by using the quote crate here):



    let name = &input.ident;

    let output = quote! {
    impl #name {
    pub fn field_count() -> usize {
    #field_count
    }
    }
    };

    // Return output tokenstream
    TokenStream::from(output)


    Then, in your application, you can write:



    #[derive(FieldCount)]
    struct MyStruct {
    first_field: i32,
    second_field: String,
    third_field: u16,
    }

    MyStruct::field_count(); // returns 3





    share|improve this answer
















    Are there any possible API like field_count() or is it only possible to get that via macros?




    There is no such built-in API that would allow you to get this information at runtime. Rust does not have runtime reflection (see this question for more information). But it is indeed possible via proc-macros!



    Note: proc-macros are different from "macro by example" (which is declared via macro_rules!). The latter is not as powerful as proc-macros.




    If this is achievable with macros, how should it be implemented?




    (This is not an introduction into proc-macros; if the topic is completely new to you, first read an introduction elsewhere.)



    In the proc-macro (for example a custom derive), you would somehow need to get the struct definition as TokenStream. The de-facto solution to use a TokenStream with Rust syntax is to parse it via syn:



    #[proc_macro_derive(FieldCount)]
    pub fn derive_field_count(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as ItemStruct);

    // ...
    }


    The type of input is ItemStruct. As you can see, it has the field fields of the type Fields. On that field you can call iter() to get an iterator over all fields of the struct, on which in turn you could call count():



    let field_count = input.fields.iter().count();


    Now you have what you want.



    Maybe you want to add this field_count() method to your type. You can do that via the custom derive (by using the quote crate here):



    let name = &input.ident;

    let output = quote! {
    impl #name {
    pub fn field_count() -> usize {
    #field_count
    }
    }
    };

    // Return output tokenstream
    TokenStream::from(output)


    Then, in your application, you can write:



    #[derive(FieldCount)]
    struct MyStruct {
    first_field: i32,
    second_field: String,
    third_field: u16,
    }

    MyStruct::field_count(); // returns 3






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 7 hours ago









    hellow

    4,86632042




    4,86632042










    answered 9 hours ago









    Lukas KalbertodtLukas Kalbertodt

    24.7k254113




    24.7k254113








    • 1





      Instead of a derive, you can also make it a custom attribute, see the reference for details

      – hellow
      8 hours ago













    • Shouldn't the last line of the macro read TokenStream::from (output) instead of TokenStream::from (expanded)?

      – Jmb
      7 hours ago











    • Note: run-time reflection is not necessary, run-time introspection or even compile-time introspection would be sufficient. And indeed, it turns out that using a derive/attribute/proc-macro is compile-time introspection.

      – Matthieu M.
      7 hours ago











    • @Jmb if you are certain, you can edit the answer next time yourself ;)

      – hellow
      7 hours ago








    • 1





      @Jmb Good catch. Sadly, I didn't have a compiler at hand when I wrote the answer. So I replaced cargo check with "looking at the code", which is always a bad idea...

      – Lukas Kalbertodt
      5 hours ago














    • 1





      Instead of a derive, you can also make it a custom attribute, see the reference for details

      – hellow
      8 hours ago













    • Shouldn't the last line of the macro read TokenStream::from (output) instead of TokenStream::from (expanded)?

      – Jmb
      7 hours ago











    • Note: run-time reflection is not necessary, run-time introspection or even compile-time introspection would be sufficient. And indeed, it turns out that using a derive/attribute/proc-macro is compile-time introspection.

      – Matthieu M.
      7 hours ago











    • @Jmb if you are certain, you can edit the answer next time yourself ;)

      – hellow
      7 hours ago








    • 1





      @Jmb Good catch. Sadly, I didn't have a compiler at hand when I wrote the answer. So I replaced cargo check with "looking at the code", which is always a bad idea...

      – Lukas Kalbertodt
      5 hours ago








    1




    1





    Instead of a derive, you can also make it a custom attribute, see the reference for details

    – hellow
    8 hours ago







    Instead of a derive, you can also make it a custom attribute, see the reference for details

    – hellow
    8 hours ago















    Shouldn't the last line of the macro read TokenStream::from (output) instead of TokenStream::from (expanded)?

    – Jmb
    7 hours ago





    Shouldn't the last line of the macro read TokenStream::from (output) instead of TokenStream::from (expanded)?

    – Jmb
    7 hours ago













    Note: run-time reflection is not necessary, run-time introspection or even compile-time introspection would be sufficient. And indeed, it turns out that using a derive/attribute/proc-macro is compile-time introspection.

    – Matthieu M.
    7 hours ago





    Note: run-time reflection is not necessary, run-time introspection or even compile-time introspection would be sufficient. And indeed, it turns out that using a derive/attribute/proc-macro is compile-time introspection.

    – Matthieu M.
    7 hours ago













    @Jmb if you are certain, you can edit the answer next time yourself ;)

    – hellow
    7 hours ago







    @Jmb if you are certain, you can edit the answer next time yourself ;)

    – hellow
    7 hours ago






    1




    1





    @Jmb Good catch. Sadly, I didn't have a compiler at hand when I wrote the answer. So I replaced cargo check with "looking at the code", which is always a bad idea...

    – Lukas Kalbertodt
    5 hours ago





    @Jmb Good catch. Sadly, I didn't have a compiler at hand when I wrote the answer. So I replaced cargo check with "looking at the code", which is always a bad idea...

    – Lukas Kalbertodt
    5 hours ago













    5














    It's possible when the struct itself is generated by the macros - in this case you can just count tokens passed into macros, as shown here. That's what I've come up with:



    macro_rules! gen {
    ($name:ident {$($field:ident : $t:ty),+}) => {
    struct $name { $($field: $t),+ }
    impl $name {
    fn field_count(&self) -> usize {
    gen!(@count $($field),+)
    }
    }
    };
    (@count $t1:tt, $($t:tt),+) => { 1 + gen!(@count $($t),+) };
    (@count $t:tt) => { 1 };
    }


    Playground (with some test cases)



    The downside for this approach (one - there could be more) is that it's not trivial to add an attribute to this function - for example, to #[derive(...)] something on it. Another approach would be to write the custom derive macros, but this is something that I can't speak about for now.






    share|improve this answer




























      5














      It's possible when the struct itself is generated by the macros - in this case you can just count tokens passed into macros, as shown here. That's what I've come up with:



      macro_rules! gen {
      ($name:ident {$($field:ident : $t:ty),+}) => {
      struct $name { $($field: $t),+ }
      impl $name {
      fn field_count(&self) -> usize {
      gen!(@count $($field),+)
      }
      }
      };
      (@count $t1:tt, $($t:tt),+) => { 1 + gen!(@count $($t),+) };
      (@count $t:tt) => { 1 };
      }


      Playground (with some test cases)



      The downside for this approach (one - there could be more) is that it's not trivial to add an attribute to this function - for example, to #[derive(...)] something on it. Another approach would be to write the custom derive macros, but this is something that I can't speak about for now.






      share|improve this answer


























        5












        5








        5







        It's possible when the struct itself is generated by the macros - in this case you can just count tokens passed into macros, as shown here. That's what I've come up with:



        macro_rules! gen {
        ($name:ident {$($field:ident : $t:ty),+}) => {
        struct $name { $($field: $t),+ }
        impl $name {
        fn field_count(&self) -> usize {
        gen!(@count $($field),+)
        }
        }
        };
        (@count $t1:tt, $($t:tt),+) => { 1 + gen!(@count $($t),+) };
        (@count $t:tt) => { 1 };
        }


        Playground (with some test cases)



        The downside for this approach (one - there could be more) is that it's not trivial to add an attribute to this function - for example, to #[derive(...)] something on it. Another approach would be to write the custom derive macros, but this is something that I can't speak about for now.






        share|improve this answer













        It's possible when the struct itself is generated by the macros - in this case you can just count tokens passed into macros, as shown here. That's what I've come up with:



        macro_rules! gen {
        ($name:ident {$($field:ident : $t:ty),+}) => {
        struct $name { $($field: $t),+ }
        impl $name {
        fn field_count(&self) -> usize {
        gen!(@count $($field),+)
        }
        }
        };
        (@count $t1:tt, $($t:tt),+) => { 1 + gen!(@count $($t),+) };
        (@count $t:tt) => { 1 };
        }


        Playground (with some test cases)



        The downside for this approach (one - there could be more) is that it's not trivial to add an attribute to this function - for example, to #[derive(...)] something on it. Another approach would be to write the custom derive macros, but this is something that I can't speak about for now.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 9 hours ago









        CerberusCerberus

        909619




        909619






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54177438%2fhow-to-programmatically-get-the-number-of-fields-of-a-struct%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Knooppunt Holsloot

            Altaar (religie)

            Gregoriusmis