Hi,
I have 2 FTP connections ( FTP1, FTP2). Each connection has some common implementations ( connect(), download, etc. ), and specific implementations ( unzip()
: files are in format .gzip
in FTP1
, files are in format .zip
in FTP
2 for instance )
I would like to be able to call them like this:
func main() {
var acqs []Acquisition
ftp, err := NewFTP(os.Getenv("FTP_USER"), os.Getenv("FTP_PASSWORD"), os.Getenv("FTP_HOST"), os.Getenv("FTP_PORT"))
if err != nil {
panic(err)
}
ftp1 := &FTP1{*ftp}
ftp2 := &FTP2{*ftp}
acqs = append(acqs, ftp1, ftp2)
for _, acq := range acqs {
meters, err := acq.FetchMeters()
if err != nil {
log.Warn(acq.Name(), " got error :", err)
}
log.Info(meters)
}
}
with :
type Acquisition interface {
FetchMeters() ([]Meter, error)
Name() string
}
type Meter struct {
ID string
OperationID string
Unit string
}
type FTP struct {
Username string
Password string
Url string
Port string
client *goftp.FTP
}
type FTP1 struct {
FTP
}
type FTP2 struct {
FTP
}
func NewFTP(user, password, url, port string) (*FTP, error) {
var err error
ftp := &FTP{
Username: user,
Password: password,
Url: url,
Port: port,
}
if ftp.client, err = goftp.Connect(url + ":" + port); err != nil {
return nil, err
}
if err = ftp.client.Login(user, password); err != nil {
return nil, err
}
return ftp, nil
}
For all FTP connection, FetchMeters() will be:
func (ftp FTP) FetchMeters() ([]Meter, error) {
log.Info(ftp.Name(), " is running")
file := ftp.Download("")
file = ftp.Unzip("") // I have several implementation of Unzip
log.Info(file)
return nil, nil
}
where Download()
is common to all FTP
structs, but Unzip()
is specific to ftp1, ftp2
Off course, in my case Unzip() doesn’t exists for FTP
type, so it will fail.
What I should do is to put the receiver as an abstract type, an interface FTPAcq
type FTPAcq interface {
Unzip(file string) string
}
func (ftp FTPAcq) FetchMeters() ([]Meter, error) {
...
}
But compiler is complaining.
I spent a lot of time figuring out how should I do, it seems easy but I can’t understand what I am missing.
Here is the full code in playground: