1

Main Problem:

I write a cli application to communicate with a http-server. The Server provides me with several endpoints and some functions under these endpoints (eg. /todo/add, /other_endpoint/del). Access to the library should represent these endpoints (eg master.todo.add(...), master.other_endpoint.del(...)).

My first attemp was to add the Master as reference to all endpoint objects.

struct Todo {
    m: Master
}

The Master holds objects to all endpoints

struct Master {
    todo: Todo,
    other_endpoint: OtherEndpoint,
    server: Server,
}

Master holds a server object to communicate with the http-server. So endpoint objects can call this server object via self.master.server.communicate().

But I have driven my rust(y) car against a recursive type 'Master' has infinite size. After that I have tried a m: &'a Master with all definitions of the lifetimes. But without success.

I have now two questions:

  1. What do I have to do to get this to work?
  2. Does another design exist (maybe a nicer one) to get this done?

Edit:

Community
  • 1
  • 1
silvio
  • 2,174
  • 20
  • 36
  • 2
    [Relevant](https://stackoverflow.com/questions/25296195/why-are-recursive-struct-types-illegal-in-rust). – squiguy Jul 13 '16 at 23:05

1 Answers1

1

As the compiler tells you Todo and Master are recursive types and thus have infinite size and you need to

insert indirection (e.g., a Box, Rc, or &) at some point

So you basically have three options:

  1. Hold Master as reference in Todo

This introduces lifetimes to your structs but should be possible:

struct Server {}

struct Todo<'a> {
    m: &'a Master<'a>
}

struct Master<'a> {
    todo: Todo<'a>,
    server: Server,
}
  1. box master

Looks simpler and you do not run into lifetime issues from the beginning on. Keep in mind though, that box have an implicit 'static lifetime. You may need to change that.

struct Server {}

struct Todo{
    m: Box<Master> // or if 'static is not what you need Box<Master + 'a>
}

struct Master {
    todo: Todo,
    server: Server,
}
  1. The last option presented to you by the compiler is a reference counted pointer to Master

Reference counting introduces a small runtime overhead. But when you're dealing with http-requests that should be negligible.

use std::rc::Rc;
struct Server {}

struct Todo{
    m: Rc<Master>
}

struct Master {
    todo: Todo,
    server: Server,
}

These are your three basic options. I would recommend you to play with them to get to know them.

JDemler
  • 1,246
  • 14
  • 22
  • Thanks for your help. I had some other issues, but the problem which I have described was answered. Thanks @Jdemler. – silvio Jul 15 '16 at 11:02