0

I have this piece of go code -

type Server struct {
    enforcerMap map[int]*casbin.Enforcer
    adapterMap  map[int]persist.Adapter
}

func NewServer() *Server {
    s := Server{}

    s.enforcerMap = map[int]*casbin.Enforcer{}
    s.adapterMap = map[int]persist.Adapter{}

    return &s
}

func (s *Server) getEnforcer(handle int) (*casbin.Enforcer, error) {
    if _, ok := s.enforcerMap[handle]; ok {
        return s.enforcerMap[handle], nil
    } else {
        return nil, errors.New("enforcer not found")
    }
}

Here casbin.Enforcer is -

type Enforcer struct {
    modelPath string
    // ...
}

link - https://github.com/casbin/casbin/blob/master/enforcer.go#L33

And persist.Adapter is -

type Adapter interface {
    // LoadPolicy loads all policy rules from the storage.
    LoadPolicy(model model.Model) error
    // ...
}

link - https://github.com/casbin/casbin/blob/master/persist/adapter.go#L47

The corresponding struct and trait in rust are -

pub struct Enforcer {
    model: Box<dyn Model>,
    // ...
}

link - https://github.com/casbin/casbin-rs/blob/master/src/enforcer.rs#L58

and

pub trait Adapter: Send + Sync {
    async fn load_policy(&self, m: &mut dyn Model) -> Result<()>;
    async fn load_filtered_policy<'a>(
        &mut self,
        m: &mut dyn Model,
        f: Filter<'a>,
    ) -> Result<()>;
    // ...
}

link - https://github.com/casbin/casbin-rs/blob/master/src/adapter/mod.rs#L22

I want to port the code to rust. I have written this struct -

pub struct Server {
    enforcerMap: Enforcer,
    adapterMap: Box<dyn Adapter>,
}

But I can't understand how to implement NewServer(), and getEnforcer() too.

Eli Bendersky
  • 263,248
  • 89
  • 350
  • 412
eth_sign
  • 63
  • 7
  • 2
    `Server` in Go hosts two maps. So why did you decide to change this in rust. Just write `enforcerMap: HashMap ...`. For such an object you can easily create a factory method initializing the maps empty. – CoronA Jun 24 '21 at 22:01

1 Answers1

1

In your go code, your NewServer() function only creates an instance of the server struct and initializes the hashmaps contained in the server instance, so your rust code for that will be similar. The hashmap rust uses is found in std::collections, along with other useful datatypes. So, editing your struct a little bit to add a map akin to the go code

use std::collections::HashMap;

pub struct Server {
    enforcerMap: HashMap<i32,Enforcer>,
    adapterMap: HashMap<i32,Box<dyn Adapter>>,
}

And then for the NewServer function

impl Server {
    pub fn NewServer()->Self {
        Self {
        enforcerMap:HashMap::new(),
        adapterMap:HashMap::new(),
        }
    }
}
Custards1
  • 123
  • 2
  • 9
  • Can you please comment on - `func (s *Server) getEnforcer(handle int) (*casbin.Enforcer, error) {}`. How do I write this function? – eth_sign Jun 25 '21 at 00:38
  • 2
    I highly recommend you look into this [link](https://doc.rust-lang.org/std/collections/struct.HashMap.html), It will solve all your problems with maps – Custards1 Jun 25 '21 at 02:59
  • 3
    @noob.rs it's impossible to answer without knowing the constraints & use cases, though `fn get_enforcer(&self, handle: i32) -> Option<&Enforcer> { self.enforcer.get(handle) }` is probably a good start. Have you considered reading the rust book or learning the language? – Masklinn Jun 25 '21 at 05:51
  • 2
    And trying to port the source project line by line sounds like anything but a great idea. – Masklinn Jun 25 '21 at 05:52
  • @Masklinn Hey, thanks for the suggestion. Yes, I'm fairly new to the rust language. Been learning from the book. – eth_sign Jun 25 '21 at 06:41