Cómo volver a exponer una caja completa en línea.
Tengo un proc-macro que también expone algunos tipos, por lo que estoy utilizando la siguiente estructura de cajas:
foo_core
exportaFooTrait
.foo_macro
(depende defoo_core
) exportafoo_macro
, que genera algunas estructuras que implementanFooTrait
.foo
(depende defoo_core
yfoo_macro
) re-exportaFooTrait
yfoo_macro
.
El problema con el que me encuentro es que al re-exportar foo_core
, cambia su ruta.
foo_macro
genera un código que se ve aproximadamente así:
struct Bar;
impl ::foo_core::FooTrait for Bar {
// ...
}
Tengo una serie de pruebas trybuild
en foo_macro
que pasan, ya que foo_core
es una caja disponible.
El problema surge cuando intento escribir pruebas en foo
(o en las cajas que dependen únicamente de foo
), porque obtengo un error que me dice que no se puede encontrar la caja foo_core
.
Esto tiene cierto sentido para mí; el consumidor de foo
no ha dependido explícitamente de foo_core
, pero me gustaría que los usuarios de mi caja no tengan que agregar foo
y foo_core
(y asegurarse de que las versiones coincidan), en su lugar, me gustaría que puedan agregar solo foo
y que funcione.
Actualmente, puedo acceder a foo_core
a través de foo::foo_core::FooTrait
, pero obviamente esto es diferente a cómo mi macro genera el código (::foo_core::FooTrait
). ¿Existe alguna forma de hacer que foo
re-exporte toda la caja foo_core
?
Si eso no es posible, ¿cuál es la mejor manera de abordar este patrón? ¿Puedo hacer que foo_macro
cambie su comportamiento según en qué caja esté definido? ¿O debería mover todas mis pruebas a foo
en lugar de foo_macro
?
https://stackoverflow.com/questions/64288426/is-there-a-way-to-have-a-public-trait-in-a-proc-macro-crate Una respuesta a esta pregunta menciona este problema, pero simplemente dice “debes usar los nombres completamente calificados”, pero mi comprensión era que esto es lo que significa el ::
al comienzo de la ruta.
Esto parece ser un patrón bastante común, así que espero que haya una solución sencilla disponible.
davy.ai
Para volver a exportar todo el paquete
foo_core
enfoo
, puedes utilizar la declaraciónpub use
con un comodín (*
) de la siguiente manera:Esto hará que todos los elementos públicos en
foo_core
estén disponibles enfoo
.En cuanto a cambiar el comportamiento de
foo_macro
dependiendo del paquete en el que esté definido, puedes utilizar el paqueteproc-macro-hack
para definir una macro “hack” que se expanda a un código diferente dependiendo de si se invoca en el contexto defoo
o no. Por ejemplo:Luego, en el archivo
Cargo.toml
defoo
, puedes habilitar la funciónfoo
de la siguiente manera:Finalmente, en tus pruebas, puedes activar la función
foo
de la siguiente manera:De esta manera, los usuarios de tu paquete pueden depender únicamente de
foo
y obtener tantofoo_core
comofoo_macro
, y si necesitan personalizar el comportamiento defoo_macro
, pueden hacerlo utilizando la funciónfoo
.