Как я могу поделиться моделями, используя библиотеку, которая должна быть напрямую расширена в двоичном с Rust? - PullRequest
3 голосов
/ 25 января 2020

Я хочу иметь возможность совместно использовать структуры данных (модели) в базе кода для службы, которую я создаю. В настоящее время я разделил код в библиотеке с именем domain и двоичном файле с именем log_service.

. В библиотеке domain я определил структуру, которая будет содержать информацию для журнала, как показано ниже. .

pub struct Log {
    pub id: u32,
    pub message: String,
}

В двоичном файле log_service я хочу использовать дизель в качестве базы данных ORM и использовать эту структуру, определенную в библиотеке domain, в качестве таблицы. Дизельная документация гласит, что для использования этой структуры в качестве таблицы базы данных вам необходимо получить определенные признаки (например, Queryable) и, возможно, применить другие атрибуты.

Однако Rust не позволяет расширять эту структуру из в другом ящике, и поскольку в Rust не существует наследования, обычно существует возможность использования композиции для переноса журнала domain. Но поскольку дизель использует структуру для непосредственного сопоставления с таблицей, невозможно использовать композицию для отображения полей, потому что они должны быть верхнего уровня в структуре.

Желательно, чтобы я не хотел копировать, вставлять это структура в обоих ящиках. Я думал об использовании макроса для генерации этих структур в обеих кодовых базах из одного источника, который все же позволил бы расширить Log в двоичном файле.

Каков оптимальный способ решить эту проблему?

1 Ответ

0 голосов
/ 25 января 2020

Нет. Это невозможно (легко) сделать, если вам абсолютно необходимо поддерживать текущую структуру вашего проекта.

Rust's orphan rules состояния:

. .. что каждая реализация черты должна удовлетворять одному из следующих условий:

  1. Реализуемая черта определена в том же ящике.

  2. В хотя бы один из параметров типа Self или универсального c свойства должен соответствовать следующей грамматике, где C - это номинальный тип, определенный в контейнере для хранения:

 T = C
   | &C
   | &mut C
   | Box<C>

Проще говоря, либо черта, либо структура должны быть локальными по отношению к ящику, чтобы вы могли его реализовать.

Так что самым простым вариантом для вас было бы получить diesel::deserialize::Queryable для вашей Log структуры в domain ящике.

...