* [rust-dev] Encapsulating mutiple generic types
@ 2014-12-01 15:59 Ryan Michael
2014-12-01 16:04 ` Federico Ravasio
0 siblings, 1 reply; 5+ messages in thread
From: Ryan Michael @ 2014-12-01 15:59 UTC (permalink / raw)
To: rust-dev
[-- Attachment #1: Type: text/plain, Size: 1508 bytes --]
I'm curious if the community has some design approaches to encapsulating
interfaces to multiple generic implementations. For example, imagine I was
writing an abstract database interface with multiple backing
implementations for different stores (sqlite, pgsql, mysql, etc) and
logging data to different types of loggers (stdout, file, network-attached,
etc). The goal would be to implement some shared methods (insert, query,
delete) to be delegated to different stores, with logging about the results.
My first approach to this was to create traits, and use them in a struct
trait Logger {
fn log(&mut self, message: String),
}
trait Store {
fn insert(&mut self, value: String),
fn query(&mut self, conditions: String) -> Vec<String>,
fn delete(&mut self, value: String),
}
struct Database {
db: Store,
logger: Logger,
}
AFAICT, this isn't possible - struct fields seem to require concrete types.
Another approach I've considered is using a function with a communication
channel, something like (code probably broken in multiple ways):
enum Event {
Insert(value: String),
Query(conditions, response: channel<String>),
Delete(value: String),
}
fn database(db: Database, logger: Logger, events: chan<Event>) {
loop {
match events.recv() {
// do stuff
}
}
}
let (tx, rx) = channel()
spawn {
database(db, logger, rx);
}
tx.send(Query(my_query));
This seems like it would work, but feels like a hack. Is there a better
way to do this than using channels?
-Ryan
[-- Attachment #2: Type: text/html, Size: 2078 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [rust-dev] Encapsulating mutiple generic types
2014-12-01 15:59 [rust-dev] Encapsulating mutiple generic types Ryan Michael
@ 2014-12-01 16:04 ` Federico Ravasio
2014-12-01 19:48 ` Philippe Daouadi
0 siblings, 1 reply; 5+ messages in thread
From: Federico Ravasio @ 2014-12-01 16:04 UTC (permalink / raw)
To: Ryan Michael; +Cc: rust-dev
понедельник, 1 декабря 2014 г. в 16:59, Ryan Michael написал:
> I'm curious if the community has some design approaches to encapsulating interfaces to multiple generic implementations. For example, imagine I was writing an abstract database interface with multiple backing implementations for different stores (sqlite, pgsql, mysql, etc) and logging data to different types of loggers (stdout, file, network-attached, etc). The goal would be to implement some shared methods (insert, query, delete) to be delegated to different stores, with logging about the results.
>
> My first approach to this was to create traits, and use them in a struct
>
> trait Logger {
> fn log(&mut self, message: String),
> }
>
> trait Store {
> fn insert(&mut self, value: String),
> fn query(&mut self, conditions: String) -> Vec<String>,
> fn delete(&mut self, value: String),
> }
>
> struct Database {
> db: Store,
> logger: Logger,
> }
>
> AFAICT, this isn't possible - struct fields seem to require concrete types.
>
Hello Ryan,
I’ve had some luck by wrapping trait fields into boxes, with explicit lifetimes.
This should work:
struct Database<'a> {
db: Box<Store + 'a>,
logger: Box<Logger + 'a>,
}
Now, I’m not sure if that’s a community-accepted solution. Let’s see what the others think. :)
Cheers,
Federico
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [rust-dev] Encapsulating mutiple generic types
2014-12-01 16:04 ` Federico Ravasio
@ 2014-12-01 19:48 ` Philippe Daouadi
2014-12-01 20:25 ` Tim Kuehn
2014-12-01 20:37 ` Ben Foppa
0 siblings, 2 replies; 5+ messages in thread
From: Philippe Daouadi @ 2014-12-01 19:48 UTC (permalink / raw)
To: rust-dev
Hi,
In my project, I use something like:
struct Database {
db: Box<Store + 'static>,
logger: Box<Logger + 'static>,
}
Does anyone know what is the difference? They seem to work the same to me.
Philippe
On 12/01/2014 05:04 PM, Federico Ravasio wrote:
> понедельник, 1 декабря 2014 г. в 16:59, Ryan Michael написал:
>> I'm curious if the community has some design approaches to encapsulating interfaces to multiple generic implementations. For example, imagine I was writing an abstract database interface with multiple backing implementations for different stores (sqlite, pgsql, mysql, etc) and logging data to different types of loggers (stdout, file, network-attached, etc). The goal would be to implement some shared methods (insert, query, delete) to be delegated to different stores, with logging about the results.
>>
>> My first approach to this was to create traits, and use them in a struct
>>
>> trait Logger {
>> fn log(&mut self, message: String),
>> }
>>
>> trait Store {
>> fn insert(&mut self, value: String),
>> fn query(&mut self, conditions: String) -> Vec<String>,
>> fn delete(&mut self, value: String),
>> }
>>
>> struct Database {
>> db: Store,
>> logger: Logger,
>> }
>>
>> AFAICT, this isn't possible - struct fields seem to require concrete types.
>>
> Hello Ryan,
> I’ve had some luck by wrapping trait fields into boxes, with explicit lifetimes.
>
> This should work:
>
> struct Database<'a> {
> db: Box<Store + 'a>,
> logger: Box<Logger + 'a>,
> }
>
>
> Now, I’m not sure if that’s a community-accepted solution. Let’s see what the others think. :)
>
> Cheers,
> Federico
>
> _______________________________________________
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [rust-dev] Encapsulating mutiple generic types
2014-12-01 19:48 ` Philippe Daouadi
@ 2014-12-01 20:25 ` Tim Kuehn
2014-12-01 20:37 ` Ben Foppa
1 sibling, 0 replies; 5+ messages in thread
From: Tim Kuehn @ 2014-12-01 20:25 UTC (permalink / raw)
To: Philippe Daouadi; +Cc: rust-dev
[-- Attachment #1: Type: text/plain, Size: 2279 bytes --]
Can you use a trait for that?
trait Database: Store + Logger {}
On Mon, Dec 1, 2014 at 11:48 AM, Philippe Daouadi <blastrock0@free.fr>
wrote:
> Hi,
>
> In my project, I use something like:
>
> struct Database {
> db: Box<Store + 'static>,
> logger: Box<Logger + 'static>,
> }
>
> Does anyone know what is the difference? They seem to work the same to me.
>
> Philippe
>
>
> On 12/01/2014 05:04 PM, Federico Ravasio wrote:
>
>> понедельник, 1 декабря 2014 г. в 16:59, Ryan Michael написал:
>>
>>> I'm curious if the community has some design approaches to encapsulating
>>> interfaces to multiple generic implementations. For example, imagine I was
>>> writing an abstract database interface with multiple backing
>>> implementations for different stores (sqlite, pgsql, mysql, etc) and
>>> logging data to different types of loggers (stdout, file, network-attached,
>>> etc). The goal would be to implement some shared methods (insert, query,
>>> delete) to be delegated to different stores, with logging about the results.
>>> My first approach to this was to create traits, and use them in a
>>> struct
>>> trait Logger {
>>> fn log(&mut self, message: String),
>>> }
>>> trait Store {
>>> fn insert(&mut self, value: String),
>>> fn query(&mut self, conditions: String) -> Vec<String>,
>>> fn delete(&mut self, value: String),
>>> }
>>> struct Database {
>>> db: Store,
>>> logger: Logger,
>>> }
>>> AFAICT, this isn't possible - struct fields seem to require concrete
>>> types.
>>>
>>>
>> Hello Ryan,
>> I’ve had some luck by wrapping trait fields into boxes, with explicit
>> lifetimes.
>>
>> This should work:
>>
>> struct Database<'a> {
>> db: Box<Store + 'a>,
>> logger: Box<Logger + 'a>,
>> }
>>
>>
>> Now, I’m not sure if that’s a community-accepted solution. Let’s see what
>> the others think. :)
>>
>> Cheers,
>> Federico
>>
>> _______________________________________________
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>
> _______________________________________________
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
[-- Attachment #2: Type: text/html, Size: 3355 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [rust-dev] Encapsulating mutiple generic types
2014-12-01 19:48 ` Philippe Daouadi
2014-12-01 20:25 ` Tim Kuehn
@ 2014-12-01 20:37 ` Ben Foppa
1 sibling, 0 replies; 5+ messages in thread
From: Ben Foppa @ 2014-12-01 20:37 UTC (permalink / raw)
To: Philippe Daouadi; +Cc: rust-dev
[-- Attachment #1: Type: text/plain, Size: 2494 bytes --]
I think 'static is the global lifetime - that might require that the
objects can exist for as long as the program does.
also FWIW, I'm pretty sure these kinds of discussions are better-suited for
stack overflow. The mailing list is somewhat deprecated, at least
unofficially.
On Mon, Dec 1, 2014 at 11:48 AM, Philippe Daouadi <blastrock0@free.fr>
wrote:
> Hi,
>
> In my project, I use something like:
>
> struct Database {
> db: Box<Store + 'static>,
> logger: Box<Logger + 'static>,
> }
>
> Does anyone know what is the difference? They seem to work the same to me.
>
> Philippe
>
>
> On 12/01/2014 05:04 PM, Federico Ravasio wrote:
>
>> понедельник, 1 декабря 2014 г. в 16:59, Ryan Michael написал:
>>
>>> I'm curious if the community has some design approaches to encapsulating
>>> interfaces to multiple generic implementations. For example, imagine I was
>>> writing an abstract database interface with multiple backing
>>> implementations for different stores (sqlite, pgsql, mysql, etc) and
>>> logging data to different types of loggers (stdout, file, network-attached,
>>> etc). The goal would be to implement some shared methods (insert, query,
>>> delete) to be delegated to different stores, with logging about the results.
>>> My first approach to this was to create traits, and use them in a
>>> struct
>>> trait Logger {
>>> fn log(&mut self, message: String),
>>> }
>>> trait Store {
>>> fn insert(&mut self, value: String),
>>> fn query(&mut self, conditions: String) -> Vec<String>,
>>> fn delete(&mut self, value: String),
>>> }
>>> struct Database {
>>> db: Store,
>>> logger: Logger,
>>> }
>>> AFAICT, this isn't possible - struct fields seem to require concrete
>>> types.
>>>
>>>
>> Hello Ryan,
>> I’ve had some luck by wrapping trait fields into boxes, with explicit
>> lifetimes.
>>
>> This should work:
>>
>> struct Database<'a> {
>> db: Box<Store + 'a>,
>> logger: Box<Logger + 'a>,
>> }
>>
>>
>> Now, I’m not sure if that’s a community-accepted solution. Let’s see what
>> the others think. :)
>>
>> Cheers,
>> Federico
>>
>> _______________________________________________
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>
> _______________________________________________
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
[-- Attachment #2: Type: text/html, Size: 3531 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2014-12-01 20:37 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-01 15:59 [rust-dev] Encapsulating mutiple generic types Ryan Michael
2014-12-01 16:04 ` Federico Ravasio
2014-12-01 19:48 ` Philippe Daouadi
2014-12-01 20:25 ` Tim Kuehn
2014-12-01 20:37 ` Ben Foppa
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox